forked from boostorg/regex
182 lines
4.0 KiB
C++
182 lines
4.0 KiB
C++
![]() |
/*
|
||
|
*
|
||
|
* Copyright (c) 2004
|
||
|
* Dr John Maddock
|
||
|
*
|
||
|
* Use, modification and distribution are subject to the
|
||
|
* Boost Software License, Version 1.0. (See accompanying file
|
||
|
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* LOCATION: see http://www.boost.org for most recent version.
|
||
|
* FILE static_mutex_test.cpp
|
||
|
* VERSION see <boost/version.hpp>
|
||
|
* DESCRIPTION: test program for boost::static_mutex.
|
||
|
*/
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <boost/regex/pending/static_mutex.hpp>
|
||
|
#include <boost/thread/thread.hpp>
|
||
|
#include <boost/timer.hpp>
|
||
|
|
||
|
//
|
||
|
// we cannot use the regular Boost.Test in here: it is not thread safe
|
||
|
// and calls to BOOST_TEST will eventually crash on some compilers
|
||
|
// (Borland certainly) due to race conditions inside the Boost.Test lib.
|
||
|
//
|
||
|
#define BOOST_TEST(pred) if(!(pred)) failed_test(__FILE__, __LINE__, BOOST_STRINGIZE(pred));
|
||
|
|
||
|
int total_failures = 0;
|
||
|
void failed_test(const char* file, int line, const char* pred)
|
||
|
{
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
boost::static_mutex::scoped_lock guard(mut);
|
||
|
++total_failures;
|
||
|
std::cout << "Failed test in \"" << file << "\" at line " << line << ": " << pred << std::endl;
|
||
|
}
|
||
|
|
||
|
void print_cycles(int c)
|
||
|
{
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
boost::static_mutex::scoped_lock guard(mut);
|
||
|
std::cout << "Thread exited after " << c << " cycles." << std::endl;
|
||
|
}
|
||
|
|
||
|
bool sufficient_time()
|
||
|
{
|
||
|
// return true if enough time has passed since the tests began:
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
boost::static_mutex::scoped_lock guard(mut);
|
||
|
static boost::timer t;
|
||
|
// is 10 seconds enough?
|
||
|
return t.elapsed() >= 10.0;
|
||
|
}
|
||
|
|
||
|
// define three trivial test proceedures:
|
||
|
bool t1()
|
||
|
{
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
static int has_lock = 0;
|
||
|
static int data = 10000;
|
||
|
|
||
|
boost::static_mutex::scoped_lock guard(mut);
|
||
|
BOOST_TEST(++has_lock == 1);
|
||
|
BOOST_TEST(guard.locked());
|
||
|
BOOST_TEST(guard);
|
||
|
bool result = (--data > 0) ? true : false;
|
||
|
BOOST_TEST(--has_lock == 0);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
bool t2()
|
||
|
{
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
static int has_lock = 0;
|
||
|
static int data = 10000;
|
||
|
|
||
|
boost::static_mutex::scoped_lock guard(mut, false);
|
||
|
BOOST_TEST(0 == guard.locked());
|
||
|
BOOST_TEST(!guard);
|
||
|
guard.lock();
|
||
|
BOOST_TEST(++has_lock == 1);
|
||
|
BOOST_TEST(guard.locked());
|
||
|
BOOST_TEST(guard);
|
||
|
bool result = (--data > 0) ? true : false;
|
||
|
BOOST_TEST(--has_lock == 0);
|
||
|
guard.unlock();
|
||
|
BOOST_TEST(0 == guard.locked());
|
||
|
BOOST_TEST(!guard);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
bool t3()
|
||
|
{
|
||
|
static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ;
|
||
|
static int has_lock = 0;
|
||
|
static int data = 10000;
|
||
|
|
||
|
boost::static_mutex::scoped_lock guard(mut);
|
||
|
BOOST_TEST(++has_lock == 1);
|
||
|
BOOST_TEST(guard.locked());
|
||
|
BOOST_TEST(guard);
|
||
|
bool result = (--data > 0) ? true : false;
|
||
|
BOOST_TEST(--has_lock == 0);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
// define their thread procs:
|
||
|
void thread1_proc()
|
||
|
{
|
||
|
int cycles = 0;
|
||
|
while(!sufficient_time())
|
||
|
{
|
||
|
t1();
|
||
|
t2();
|
||
|
++cycles;
|
||
|
}
|
||
|
print_cycles(cycles);
|
||
|
}
|
||
|
|
||
|
void thread2_proc()
|
||
|
{
|
||
|
int cycles = 0;
|
||
|
while(!sufficient_time())
|
||
|
{
|
||
|
t2();
|
||
|
t3();
|
||
|
++cycles;
|
||
|
}
|
||
|
print_cycles(cycles);
|
||
|
}
|
||
|
|
||
|
void thread3_proc()
|
||
|
{
|
||
|
int cycles = 0;
|
||
|
while(!sufficient_time())
|
||
|
{
|
||
|
t1();
|
||
|
t3();
|
||
|
++cycles;
|
||
|
}
|
||
|
print_cycles(cycles);
|
||
|
}
|
||
|
|
||
|
// make sure that at least one of our test proceedures
|
||
|
// is called during program startup:
|
||
|
struct startup1
|
||
|
{
|
||
|
startup1()
|
||
|
{
|
||
|
t1();
|
||
|
}
|
||
|
~startup1()
|
||
|
{
|
||
|
t1();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
startup1 up1;
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
BOOST_TEST(0 != &up1);
|
||
|
|
||
|
boost::thread thrd1(&thread1_proc);
|
||
|
boost::thread thrd2(&thread1_proc);
|
||
|
boost::thread thrd3(&thread2_proc);
|
||
|
boost::thread thrd4(&thread2_proc);
|
||
|
boost::thread thrd5(&thread3_proc);
|
||
|
boost::thread thrd6(&thread3_proc);
|
||
|
|
||
|
thrd1.join();
|
||
|
thrd2.join();
|
||
|
thrd3.join();
|
||
|
thrd4.join();
|
||
|
thrd5.join();
|
||
|
thrd6.join();
|
||
|
|
||
|
return total_failures;
|
||
|
}
|