123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /*
- *
- * Copyright (c) 2004
- * 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 <boost/regex/pending/static_mutex.hpp>
- #include <boost/thread/thread.hpp>
- #include <boost/timer.hpp>
- #include <iostream>
- #include <iomanip>
- //
- // we cannot use the regular Boost.Test in here: it is not thread safe
- // and calls to BOOST_CHECK will eventually crash on some compilers
- // (Borland certainly) due to race conditions inside the Boost.Test lib.
- //
- #define BOOST_CHECK(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_CHECK(++has_lock == 1);
- BOOST_CHECK(guard.locked());
- BOOST_CHECK(guard);
- bool result = (--data > 0) ? true : false;
- BOOST_CHECK(--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_CHECK(0 == guard.locked());
- BOOST_CHECK(!guard);
- guard.lock();
- BOOST_CHECK(++has_lock == 1);
- BOOST_CHECK(guard.locked());
- BOOST_CHECK(guard);
- bool result = (--data > 0) ? true : false;
- BOOST_CHECK(--has_lock == 0);
- guard.unlock();
- BOOST_CHECK(0 == guard.locked());
- BOOST_CHECK(!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_CHECK(++has_lock == 1);
- BOOST_CHECK(guard.locked());
- BOOST_CHECK(guard);
- bool result = (--data > 0) ? true : false;
- BOOST_CHECK(--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()
- {
- (void)up1;
-
- std::list<boost::shared_ptr<boost::thread> > threads;
- for(int i = 0; i < 2; ++i)
- {
- try{
- threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread1_proc)));
- }
- catch(const std::exception& e)
- {
- std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl;
- }
- }
- for(int i = 0; i < 2; ++i)
- {
- try{
- threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread2_proc)));
- }
- catch(const std::exception& e)
- {
- std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl;
- }
- }
- for(int i = 0; i < 2; ++i)
- {
- try{
- threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread3_proc)));
- }
- catch(const std::exception& e)
- {
- std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl;
- }
- }
- std::list<boost::shared_ptr<boost::thread> >::const_iterator a(threads.begin()), b(threads.end());
- while(a != b)
- {
- (*a)->join();
- ++a;
- }
- return total_failures;
- }
|