diff --git a/test/test_condition.cpp b/test/test_condition.cpp index 0caf888e..0e7ac037 100644 --- a/test/test_condition.cpp +++ b/test/test_condition.cpp @@ -6,77 +6,74 @@ #include "util.inl" -namespace +struct condition_test_data { - struct condition_test_data - { - condition_test_data() : notified(0), awoken(0) { } + condition_test_data() : notified(0), awoken(0) { } - boost::mutex mutex; - boost::condition condition; - int notified; - int awoken; - }; + boost::mutex mutex; + boost::condition condition; + int notified; + int awoken; +}; - void condition_test_thread(condition_test_data* data) - { - boost::mutex::scoped_lock lock(data->mutex); - BOOST_CHECK(lock ? true : false); - while (!(data->notified > 0)) - data->condition.wait(lock); - BOOST_CHECK(lock ? true : false); - data->awoken++; - } +void condition_test_thread(condition_test_data* data) +{ + boost::mutex::scoped_lock lock(data->mutex); + BOOST_CHECK(lock ? true : false); + while (!(data->notified > 0)) + data->condition.wait(lock); + BOOST_CHECK(lock ? true : false); + data->awoken++; +} - struct cond_predicate - { - cond_predicate(int& var, int val) : _var(var), _val(val) { } +struct cond_predicate +{ + cond_predicate(int& var, int val) : _var(var), _val(val) { } - bool operator()() { return _var == _val; } + bool operator()() { return _var == _val; } - int& _var; - int _val; - }; + int& _var; + int _val; +}; - void condition_test_waits(condition_test_data* data) - { - boost::mutex::scoped_lock lock(data->mutex); - BOOST_CHECK(lock ? true : false); +void condition_test_waits(condition_test_data* data) +{ + boost::mutex::scoped_lock lock(data->mutex); + BOOST_CHECK(lock ? true : false); - // Test wait. - while (data->notified != 1) - data->condition.wait(lock); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 1); - data->awoken++; - data->condition.notify_one(); + // Test wait. + while (data->notified != 1) + data->condition.wait(lock); + BOOST_CHECK(lock ? true : false); + BOOST_CHECK_EQUAL(data->notified, 1); + data->awoken++; + data->condition.notify_one(); - // Test predicate wait. - data->condition.wait(lock, cond_predicate(data->notified, 2)); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 2); - data->awoken++; - data->condition.notify_one(); + // Test predicate wait. + data->condition.wait(lock, cond_predicate(data->notified, 2)); + BOOST_CHECK(lock ? true : false); + BOOST_CHECK_EQUAL(data->notified, 2); + data->awoken++; + data->condition.notify_one(); - // Test timed_wait. - boost::xtime xt = delay(10); - while (data->notified != 3) - data->condition.timed_wait(lock, xt); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK_EQUAL(data->notified, 3); - data->awoken++; - data->condition.notify_one(); + // Test timed_wait. + boost::xtime xt = delay(10); + while (data->notified != 3) + data->condition.timed_wait(lock, xt); + BOOST_CHECK(lock ? true : false); + BOOST_CHECK_EQUAL(data->notified, 3); + data->awoken++; + data->condition.notify_one(); - // Test predicate timed_wait. - xt = delay(10); - cond_predicate pred(data->notified, 4); - BOOST_CHECK(data->condition.timed_wait(lock, xt, pred)); - BOOST_CHECK(lock ? true : false); - BOOST_CHECK(pred()); - BOOST_CHECK_EQUAL(data->notified, 4); - data->awoken++; - data->condition.notify_one(); - } + // Test predicate timed_wait. + xt = delay(10); + cond_predicate pred(data->notified, 4); + BOOST_CHECK(data->condition.timed_wait(lock, xt, pred)); + BOOST_CHECK(lock ? true : false); + BOOST_CHECK(pred()); + BOOST_CHECK_EQUAL(data->notified, 4); + data->awoken++; + data->condition.notify_one(); } void do_test_condition_notify_one() diff --git a/test/test_mutex.cpp b/test/test_mutex.cpp index 08417f24..ff5dc3d7 100644 --- a/test/test_mutex.cpp +++ b/test/test_mutex.cpp @@ -6,22 +6,8 @@ #include #include -namespace -{ - inline bool xtime_in_range(boost::xtime& xt, int less_seconds, int greater_seconds) - { - boost::xtime cur; - BOOST_CHECK_EQUAL(boost::xtime_get(&cur, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - - boost::xtime less = cur; - less.sec += less_seconds; - - boost::xtime greater = cur; - greater.sec += greater_seconds; - - return (boost::xtime_cmp(xt, less) >= 0) && (boost::xtime_cmp(xt, greater) <= 0); - } -} +#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only +#include "util.inl" template struct test_lock @@ -43,9 +29,7 @@ struct test_lock BOOST_CHECK(lock ? true : false); // Construct and initialize an xtime for a fast time out. - boost::xtime xt; - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.nsec += 100000000; + boost::xtime xt = delay(0, 100); // Test the lock and the mutex with condition variables. // No one is going to notify this condition variable. We expect to @@ -85,9 +69,7 @@ struct test_trylock BOOST_CHECK(lock ? true : false); // Construct and initialize an xtime for a fast time out. - boost::xtime xt; - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.nsec += 100000000; + boost::xtime xt = delay(0, 100); // Test the lock and the mutex with condition variables. // No one is going to notify this condition variable. We expect to @@ -121,9 +103,7 @@ struct test_timedlock // Test the lock's constructors. { // Construct and initialize an xtime for a fast time out. - boost::xtime xt; - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.nsec += 100000000; + boost::xtime xt = delay(0, 100); timed_lock_type lock(mutex, xt); BOOST_CHECK(lock ? true : false); @@ -136,16 +116,14 @@ struct test_timedlock BOOST_CHECK(lock ? true : false); // Construct and initialize an xtime for a fast time out. - boost::xtime xt; - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.nsec += 100000000; + boost::xtime xt = delay(0, 100); // Test the lock and the mutex with condition variables. // No one is going to notify this condition variable. We expect to // time out. BOOST_CHECK(!condition.timed_wait(lock, xt)); BOOST_CHECK(lock ? true : false); - BOOST_CHECK(xtime_in_range(xt, -1, 0)); + BOOST_CHECK(in_range(xt)); // Test the lock, unlock and timedlock methods. lock.unlock(); @@ -154,8 +132,7 @@ struct test_timedlock BOOST_CHECK(lock ? true : false); lock.unlock(); BOOST_CHECK(!lock); - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.nsec += 100000000; + xt = delay(0, 100); BOOST_CHECK(lock.timed_lock(xt)); BOOST_CHECK(lock ? true : false); } @@ -175,38 +152,63 @@ struct test_recursive_lock } }; -void test_mutex() +void do_test_mutex() { test_lock()(); } -void test_try_mutex() +void test_mutex() +{ + timed_test(&do_test_mutex, 3); +} + +void do_test_try_mutex() { test_lock()(); test_trylock()(); } -void test_timed_mutex() +void test_try_mutex() +{ + timed_test(&do_test_try_mutex, 3); +} + +void do_test_timed_mutex() { test_lock()(); test_trylock()(); test_timedlock()(); } -void test_recursive_mutex() +void test_timed_mutex() +{ + timed_test(&do_test_timed_mutex, 3); +} + +void do_test_recursive_mutex() { test_lock()(); test_recursive_lock()(); } -void test_recursive_try_mutex() +void test_recursive_mutex() +{ + timed_test(&do_test_recursive_mutex, 3); +} + +void do_test_recursive_try_mutex() { test_lock()(); test_trylock()(); test_recursive_lock()(); } -void test_recursive_timed_mutex() +void test_recursive_try_mutex() +{ + timed_test(&do_test_recursive_try_mutex, 3); +} + +void do_test_recursive_timed_mutex() { test_lock()(); test_trylock()(); @@ -214,6 +216,11 @@ void test_recursive_timed_mutex() test_recursive_lock()(); } +void test_recursive_timed_mutex() +{ + timed_test(&do_test_recursive_timed_mutex, 3); +} + boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) { boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: mutex test suite"); diff --git a/test/test_once.cpp b/test/test_once.cpp index 1d4bb08d..4a82381b 100644 --- a/test/test_once.cpp +++ b/test/test_once.cpp @@ -3,23 +3,22 @@ #include -namespace +#include "util.inl" + +int once_value = 0; +boost::once_flag once = BOOST_ONCE_INIT; + +void init_once_value() { - int once_value = 0; - boost::once_flag once = BOOST_ONCE_INIT; - - void init_once_value() - { - once_value++; - } - - void test_once_thread() - { - boost::call_once(init_once_value, once); - } + once_value++; } -void test_once() +void test_once_thread() +{ + boost::call_once(init_once_value, once); +} + +void do_test_once() { const int NUMTHREADS=5; boost::thread_group threads; @@ -29,6 +28,11 @@ void test_once() BOOST_CHECK_EQUAL(once_value, 1); } +void test_once() +{ + timed_test(&do_test_once, 2); +} + boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) { boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: once test suite"); diff --git a/test/test_thread.cpp b/test/test_thread.cpp index e611985e..97f637fe 100644 --- a/test/test_thread.cpp +++ b/test/test_thread.cpp @@ -3,66 +3,33 @@ #include -namespace +#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only +#include "util.inl" + +int test_value; + +void simple_thread() { - inline bool xtime_in_range(boost::xtime& xt, int less_seconds, int greater_seconds) - { - boost::xtime cur; - BOOST_CHECK_EQUAL(boost::xtime_get(&cur, boost::TIME_UTC), static_cast(boost::TIME_UTC)); + test_value = 999; +} - boost::xtime less = cur; - less.sec += less_seconds; - - boost::xtime greater = cur; - greater.sec += greater_seconds; - - return (boost::xtime_cmp(xt, less) >= 0) && (boost::xtime_cmp(xt, greater) <= 0); - } - - int test_value; - - void simple_thread() - { - test_value = 999; - } - - struct thread_adapter - { - thread_adapter(void (*func)(boost::thread& parent), boost::thread& parent) - : func(func), parent(parent) - { - } - - void operator()() - { - (*func)(parent); - } - - void (*func)(boost::thread& parent); - boost::thread& parent; - }; - - void comparison_thread(boost::thread& parent) - { - boost::thread thrd; - BOOST_TEST(thrd != parent); - BOOST_TEST(thrd == boost::thread()); - } +void comparison_thread(boost::thread* parent) +{ + boost::thread thrd; + BOOST_TEST(thrd != *parent); + BOOST_TEST(thrd == boost::thread()); } void test_sleep() { - boost::xtime xt; - BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.sec += 3; - + boost::xtime xt = delay(3); boost::thread::sleep(xt); // Insure it's in a range instead of checking actual equality due to time lapse - BOOST_CHECK(xtime_in_range(xt, -1, 0)); + BOOST_CHECK(in_range(xt)); } -void test_creation() +void do_test_creation() { test_value = 0; boost::thread thrd(&simple_thread); @@ -70,13 +37,23 @@ void test_creation() BOOST_CHECK_EQUAL(test_value, 999); } -void test_comparison() +void test_creation() +{ + timed_test(&do_test_creation, 1); +} + +void do_test_comparison() { boost::thread self; - boost::thread thrd(thread_adapter(comparison_thread, self)); + boost::thread thrd(bind(&comparison_thread, &self)); thrd.join(); } +void test_comparison() +{ + timed_test(&do_test_comparison, 1); +} + boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) { boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: thread test suite"); diff --git a/test/test_tss.cpp b/test/test_tss.cpp index ccb4ff62..d8c325c0 100644 --- a/test/test_tss.cpp +++ b/test/test_tss.cpp @@ -4,42 +4,41 @@ #include -namespace +#include "util.inl" + +boost::mutex tss_mutex; +int tss_instances = 0; + +struct tss_value_t { - boost::mutex tss_mutex; - int tss_instances = 0; - - struct tss_value_t + tss_value_t() { - tss_value_t() - { - boost::mutex::scoped_lock lock(tss_mutex); - ++tss_instances; - value = 0; - } - ~tss_value_t() - { - boost::mutex::scoped_lock lock(tss_mutex); - --tss_instances; - } - int value; - }; - - boost::thread_specific_ptr tss_value; - - void test_tss_thread() + boost::mutex::scoped_lock lock(tss_mutex); + ++tss_instances; + value = 0; + } + ~tss_value_t() { - tss_value.reset(new tss_value_t()); - for (int i=0; i<1000; ++i) - { - int& n = tss_value->value; - BOOST_CHECK_EQUAL(n, i); - ++n; - } + boost::mutex::scoped_lock lock(tss_mutex); + --tss_instances; + } + int value; +}; + +boost::thread_specific_ptr tss_value; + +void test_tss_thread() +{ + tss_value.reset(new tss_value_t()); + for (int i=0; i<1000; ++i) + { + int& n = tss_value->value; + BOOST_CHECK_EQUAL(n, i); + ++n; } } -void test_tss() +void do_test_tss() { const int NUMTHREADS=5; boost::thread_group threads; @@ -49,6 +48,11 @@ void test_tss() BOOST_CHECK_EQUAL(tss_instances, 0); } +void test_tss() +{ + timed_test(&do_test_tss, 2); +} + boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) { boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: tss test suite"); diff --git a/test/util.inl b/test/util.inl index bfe83f21..446c039f 100644 --- a/test/util.inl +++ b/test/util.inl @@ -6,17 +6,39 @@ #include #include +#ifndef DEFAULT_EXECUTION_MONITOR_TYPE +# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition +#endif + namespace { - inline boost::xtime delay(int secs) + inline boost::xtime delay(int secs, int msecs=0, int nsecs=0) { + const int MILLISECONDS_PER_SECOND = 1000; + const int NANOSECONDS_PER_SECOND = 1000000000; + const int NANOSECONDS_PER_MILLISECOND = 1000000; + boost::xtime xt; BOOST_CHECK_EQUAL(boost::xtime_get(&xt, boost::TIME_UTC), static_cast(boost::TIME_UTC)); - xt.sec += secs; + + nsecs += xt.nsec; + msecs += nsecs / NANOSECONDS_PER_MILLISECOND; + secs += msecs / MILLISECONDS_PER_SECOND; + nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; + xt.nsec = nsecs % NANOSECONDS_PER_SECOND; + xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND); + return xt; } + inline bool in_range(const boost::xtime& xt, int secs=1) + { + boost::xtime min = delay(-secs); + boost::xtime max = delay(0); + return (boost::xtime_cmp(xt, min) >= 0) && (boost::xtime_cmp(xt, max) <= 0); + } + class execution_monitor { public: @@ -24,14 +46,16 @@ namespace execution_monitor(wait_type type, int secs) : done(false), type(type), secs(secs) { } - void start() { + void start() + { if (type != use_sleep_only) { boost::mutex::scoped_lock lock(mutex); done = false; } else { done = false; } } - void finish() { + void finish() + { if (type != use_sleep_only) { boost::mutex::scoped_lock lock(mutex); done = true; @@ -41,7 +65,8 @@ namespace done = true; } } - bool wait() { + bool wait() + { boost::xtime xt = delay(secs); if (type != use_condition) boost::thread::sleep(xt); @@ -92,7 +117,7 @@ namespace template void timed_test(F func, int secs, - execution_monitor::wait_type type=execution_monitor::use_condition) + execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE) { execution_monitor monitor(type, secs); indirect_adapter ifunc(func, monitor);