Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85794 - in trunk: boost/sync/detail boost/sync/mutexes boost/sync/support libs/sync/test libs/sync/test/run
From: andrey.semashev_at_[hidden]
Date: 2013-09-19 16:27:08


Author: andysem
Date: 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013)
New Revision: 85794
URL: http://svn.boost.org/trac/boost/changeset/85794

Log:
Bug fixes. Preliminary test for mutex added.

Added:
   trunk/libs/sync/test/run/
   trunk/libs/sync/test/run/event_test.cpp
      - copied unchanged from r85792, trunk/libs/sync/test/event_test.cpp
   trunk/libs/sync/test/run/mutex_test.cpp (contents, props changed)
   trunk/libs/sync/test/run/semaphore_test.cpp
      - copied unchanged from r85792, trunk/libs/sync/test/semaphore_test.cpp
   trunk/libs/sync/test/run/utils.hpp (contents, props changed)
Deleted:
   trunk/libs/sync/test/event_test.cpp
   trunk/libs/sync/test/semaphore_test.cpp
Text files modified:
   trunk/boost/sync/detail/interlocked.hpp | 10
   trunk/boost/sync/mutexes/timed_mutex.hpp | 2
   trunk/boost/sync/support/date_time.hpp | 4
   trunk/libs/sync/test/Jamfile.v2 | 3
   /dev/null | 144 -----------------
   trunk/libs/sync/test/run/event_test.cpp | 144 +++++++++++++++++
   trunk/libs/sync/test/run/mutex_test.cpp | 330 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/sync/test/run/semaphore_test.cpp | 113 +++++++++++++
   trunk/libs/sync/test/run/utils.hpp | 223 +++++++++++++++++++++++++++
   /dev/null | 113 -------------
   10 files changed, 821 insertions(+), 265 deletions(-)

Modified: trunk/boost/sync/detail/interlocked.hpp
==============================================================================
--- trunk/boost/sync/detail/interlocked.hpp Thu Sep 19 16:04:47 2013 (r85793)
+++ trunk/boost/sync/detail/interlocked.hpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -144,7 +144,7 @@
 #undef BOOST_SYNC_DETAIL_BTS_DEFINED
 
 #if defined(__INTEL_COMPILER)
-#define BOOST_SYNC_COMPILER_BARRIER __memory_barrier();
+#define BOOST_SYNC_COMPILER_BARRIER() __memory_barrier()
 #elif defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE)
 extern "C" void _ReadWriteBarrier(void);
 #pragma intrinsic(_ReadWriteBarrier)
@@ -156,24 +156,24 @@
 BOOST_FORCEINLINE long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
 {
     long const res = *x;
- BOOST_SYNC_COMPILER_BARRIER;
+ BOOST_SYNC_COMPILER_BARRIER();
     return res;
 }
 BOOST_FORCEINLINE void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
 {
     void* const res = *x;
- BOOST_SYNC_COMPILER_BARRIER;
+ BOOST_SYNC_COMPILER_BARRIER();
     return res;
 }
 
 BOOST_FORCEINLINE void interlocked_write_release(long volatile* x, long value) BOOST_NOEXCEPT
 {
- BOOST_SYNC_COMPILER_BARRIER;
+ BOOST_SYNC_COMPILER_BARRIER();
     *x = value;
 }
 BOOST_FORCEINLINE void interlocked_write_release(void* volatile* x, void* value) BOOST_NOEXCEPT
 {
- BOOST_SYNC_COMPILER_BARRIER;
+ BOOST_SYNC_COMPILER_BARRIER();
     *x = value;
 }
 

Modified: trunk/boost/sync/mutexes/timed_mutex.hpp
==============================================================================
--- trunk/boost/sync/mutexes/timed_mutex.hpp Thu Sep 19 16:04:47 2013 (r85793)
+++ trunk/boost/sync/mutexes/timed_mutex.hpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -115,7 +115,7 @@
 #if defined(BOOST_SYNC_DETAIL_PLATFORM_PTHREAD)
 #include <boost/sync/detail/mutexes/timed_mutex_posix.hpp>
 #elif defined(BOOST_SYNC_DETAIL_PLATFORM_WINAPI)
-#include <boost/sync/detail/mutexes/timed_mutex_windows.hpp>
+//#include <boost/sync/detail/mutexes/timed_mutex_windows.hpp>
 #else
 #error Boost.Sync: Unsupported threading API
 #endif

Modified: trunk/boost/sync/support/date_time.hpp
==============================================================================
--- trunk/boost/sync/support/date_time.hpp Thu Sep 19 16:04:47 2013 (r85793)
+++ trunk/boost/sync/support/date_time.hpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -34,7 +34,7 @@
 template< typename T >
 struct time_traits< T, typename T::_is_boost_date_time_duration >
 {
- typedef duration_tag tag;
+ typedef time_duration_tag tag;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
@@ -80,6 +80,8 @@
 
 } // namespace detail
 
+} // namespace sync
+
 } // namespace boost
 
 #include <boost/sync/detail/footer.hpp>

Modified: trunk/libs/sync/test/Jamfile.v2
==============================================================================
--- trunk/libs/sync/test/Jamfile.v2 Thu Sep 19 16:04:47 2013 (r85793)
+++ trunk/libs/sync/test/Jamfile.v2 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -21,9 +21,10 @@
 {
    local all_rules = ;
 
- for local fileb in [ glob *.cpp ]
+ for local fileb in [ glob run/*.cpp ]
    {
       local test_id = [ MATCH "(.+)\.cpp" : [ path.basename $(fileb) ] ] ;
+ # ECHO $(test_id) ;
 
       all_rules += [ run $(fileb)
       : # additional args

Deleted: trunk/libs/sync/test/event_test.cpp
==============================================================================
--- trunk/libs/sync/test/event_test.cpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85793)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,144 +0,0 @@
-// Copyright (C) 2013 Tim Blechmann
-//
-// Distributed under 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)
-
-#include <boost/test/unit_test.hpp>
-
-#include <boost/thread.hpp>
-#include <boost/sync/event.hpp>
-
-#include <boost/typeof/typeof.hpp>
-
-BOOST_AUTO_TEST_CASE(test_event_post_wait)
-{
- boost::sync::event ev;
-
- ev.post();
- ev.wait();
-
- BOOST_REQUIRE( ev.try_wait() == true );
-
- ev.reset();
-
- BOOST_REQUIRE( ev.try_wait() == false );
-}
-
-
-BOOST_AUTO_TEST_CASE(test_event_post_try_wait)
-{
- boost::sync::event ev;
-
- BOOST_REQUIRE( ev.try_wait() == false );
-
- ev.post();
-
- BOOST_REQUIRE( ev.try_wait() == true );
-}
-
-BOOST_AUTO_TEST_CASE(test_event_post_wait_autoreset)
-{
- boost::sync::event ev(true);
-
- ev.post();
- BOOST_REQUIRE( ev.try_wait() == true );
- BOOST_REQUIRE( ev.try_wait() == false );
-}
-
-
-BOOST_AUTO_TEST_CASE(test_event_reset)
-{
- boost::sync::event ev(false);
-
- BOOST_REQUIRE( ev.try_wait() == false );
- ev.post();
- BOOST_REQUIRE( ev.try_wait() == true );
- ev.reset();
- BOOST_REQUIRE( ev.try_wait() == false );
-}
-
-struct event_wait_and_post_test
-{
- void run()
- {
- boost::thread post_thread(boost::bind(&event_wait_and_post_test::wait_and_post, this));
- ev_.wait();
- }
-
- void wait_and_post()
- {
- boost::this_thread::sleep_for(boost::chrono::seconds(1));
- ev_.post();
- }
-
- boost::sync::event ev_;
- boost::thread thread_;
-};
-
-BOOST_AUTO_TEST_CASE(event_wait_and_post)
-{
- event_wait_and_post_test test;
- test.run();
-}
-
-
-BOOST_AUTO_TEST_CASE(test_event_wait_for)
-{
- using namespace boost;
-
- sync::event ev;
-
- BOOST_AUTO(start, chrono::system_clock::now());
-
- BOOST_REQUIRE( ev.try_wait() == false );
-
- BOOST_REQUIRE(!ev.try_wait_for(chrono::milliseconds(500)));
-
- BOOST_REQUIRE( ev.try_wait() == false );
-
-
- BOOST_AUTO(end, chrono::system_clock::now());
- BOOST_AUTO(wait_time, end - start);
-
- // guessing!
- BOOST_REQUIRE( wait_time > chrono::milliseconds(450) );
- BOOST_REQUIRE( wait_time < chrono::milliseconds(1000) );
-
- ev.post();
-
- BOOST_REQUIRE(ev.try_wait_for(chrono::milliseconds(500)));
-}
-
-BOOST_AUTO_TEST_CASE(test_event_wait_until)
-{
- using namespace boost;
-
- sync::event ev(0);
- {
- BOOST_AUTO(now, chrono::system_clock::now());
- BOOST_AUTO(timeout, now + chrono::milliseconds(500));
-
- BOOST_REQUIRE(!ev.try_wait_until(timeout));
-
- BOOST_AUTO(end, chrono::system_clock::now());
- BOOST_AUTO(timeout_delta, end - timeout);
-
- // guessing!
- BOOST_REQUIRE( timeout_delta > chrono::milliseconds(-400) );
- BOOST_REQUIRE( timeout_delta < chrono::milliseconds(400) );
- }
-
- ev.post();
-
- {
- BOOST_AUTO(start, chrono::system_clock::now());
- BOOST_AUTO(timeout, start + chrono::milliseconds(500));
-
- BOOST_REQUIRE(ev.try_wait_until(timeout));
-
- BOOST_AUTO(end, chrono::system_clock::now());
-
- // guessing!
- BOOST_REQUIRE( (end - start) < chrono::milliseconds(100) );
- }
-}

Copied: trunk/libs/sync/test/run/event_test.cpp (from r85792, trunk/libs/sync/test/event_test.cpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/sync/test/run/event_test.cpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794, copy of r85792, trunk/libs/sync/test/event_test.cpp)
@@ -0,0 +1,144 @@
+// Copyright (C) 2013 Tim Blechmann
+//
+// Distributed under 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)
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/thread.hpp>
+#include <boost/sync/event.hpp>
+
+#include <boost/typeof/typeof.hpp>
+
+BOOST_AUTO_TEST_CASE(test_event_post_wait)
+{
+ boost::sync::event ev;
+
+ ev.post();
+ ev.wait();
+
+ BOOST_REQUIRE( ev.try_wait() == true );
+
+ ev.reset();
+
+ BOOST_REQUIRE( ev.try_wait() == false );
+}
+
+
+BOOST_AUTO_TEST_CASE(test_event_post_try_wait)
+{
+ boost::sync::event ev;
+
+ BOOST_REQUIRE( ev.try_wait() == false );
+
+ ev.post();
+
+ BOOST_REQUIRE( ev.try_wait() == true );
+}
+
+BOOST_AUTO_TEST_CASE(test_event_post_wait_autoreset)
+{
+ boost::sync::event ev(true);
+
+ ev.post();
+ BOOST_REQUIRE( ev.try_wait() == true );
+ BOOST_REQUIRE( ev.try_wait() == false );
+}
+
+
+BOOST_AUTO_TEST_CASE(test_event_reset)
+{
+ boost::sync::event ev(false);
+
+ BOOST_REQUIRE( ev.try_wait() == false );
+ ev.post();
+ BOOST_REQUIRE( ev.try_wait() == true );
+ ev.reset();
+ BOOST_REQUIRE( ev.try_wait() == false );
+}
+
+struct event_wait_and_post_test
+{
+ void run()
+ {
+ boost::thread post_thread(boost::bind(&event_wait_and_post_test::wait_and_post, this));
+ ev_.wait();
+ }
+
+ void wait_and_post()
+ {
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ ev_.post();
+ }
+
+ boost::sync::event ev_;
+ boost::thread thread_;
+};
+
+BOOST_AUTO_TEST_CASE(event_wait_and_post)
+{
+ event_wait_and_post_test test;
+ test.run();
+}
+
+
+BOOST_AUTO_TEST_CASE(test_event_wait_for)
+{
+ using namespace boost;
+
+ sync::event ev;
+
+ BOOST_AUTO(start, chrono::system_clock::now());
+
+ BOOST_REQUIRE( ev.try_wait() == false );
+
+ BOOST_REQUIRE(!ev.try_wait_for(chrono::milliseconds(500)));
+
+ BOOST_REQUIRE( ev.try_wait() == false );
+
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+ BOOST_AUTO(wait_time, end - start);
+
+ // guessing!
+ BOOST_REQUIRE( wait_time > chrono::milliseconds(450) );
+ BOOST_REQUIRE( wait_time < chrono::milliseconds(1000) );
+
+ ev.post();
+
+ BOOST_REQUIRE(ev.try_wait_for(chrono::milliseconds(500)));
+}
+
+BOOST_AUTO_TEST_CASE(test_event_wait_until)
+{
+ using namespace boost;
+
+ sync::event ev(0);
+ {
+ BOOST_AUTO(now, chrono::system_clock::now());
+ BOOST_AUTO(timeout, now + chrono::milliseconds(500));
+
+ BOOST_REQUIRE(!ev.try_wait_until(timeout));
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+ BOOST_AUTO(timeout_delta, end - timeout);
+
+ // guessing!
+ BOOST_REQUIRE( timeout_delta > chrono::milliseconds(-400) );
+ BOOST_REQUIRE( timeout_delta < chrono::milliseconds(400) );
+ }
+
+ ev.post();
+
+ {
+ BOOST_AUTO(start, chrono::system_clock::now());
+ BOOST_AUTO(timeout, start + chrono::milliseconds(500));
+
+ BOOST_REQUIRE(ev.try_wait_until(timeout));
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+
+ // guessing!
+ BOOST_REQUIRE( (end - start) < chrono::milliseconds(100) );
+ }
+}

Added: trunk/libs/sync/test/run/mutex_test.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/sync/test/run/mutex_test.cpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -0,0 +1,330 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// Distributed under 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)
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/sync/mutexes.hpp>
+#include <boost/sync/locks.hpp>
+#include <boost/sync/support/date_time.hpp>
+//#include <boost/thread/recursive_mutex.hpp>
+//#include <boost/thread/thread_time.hpp>
+//#include <boost/thread/condition.hpp>
+
+#include "utils.hpp"
+
+template <typename M>
+struct test_lock
+{
+ typedef M mutex_type;
+ typedef boost::sync::unique_lock< mutex_type > lock_type;
+
+ void operator()() const
+ {
+ mutex_type mutex;
+// boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::sync::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+/*
+ // Construct and initialize an xtime for a fast time out.
+ 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);
+*/
+ // Test the lock and unlock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_trylock
+{
+ typedef M mutex_type;
+ typedef boost::sync::unique_lock< mutex_type > lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+// boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::sync::try_to_lock);
+ BOOST_CHECK(lock ? true : false);
+ }
+ {
+ lock_type lock(mutex, boost::sync::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex, boost::sync::try_to_lock);
+ BOOST_CHECK(lock ? true : false);
+/*
+ // Construct and initialize an xtime for a fast time out.
+ 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);
+*/
+ // Test the lock, unlock and trylock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ BOOST_CHECK(lock.try_lock());
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+/*
+template<typename Mutex>
+struct test_lock_times_out_if_other_thread_has_lock
+{
+ typedef boost::unique_lock<Mutex> Lock;
+
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_lock_times_out_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m,boost::defer_lock);
+ lock.timed_lock(boost::posix_time::milliseconds(50));
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ void locking_thread_through_constructor()
+ {
+ Lock lock(m,boost::posix_time::milliseconds(50));
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+ typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
+
+ void do_test(void (this_type::*test_func)())
+ {
+ Lock lock(m);
+
+ locked=false;
+ done=false;
+
+ boost::thread t(test_func,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+
+
+ void operator()()
+ {
+ do_test(&this_type::locking_thread);
+ do_test(&this_type::locking_thread_through_constructor);
+ }
+};
+
+template <typename M>
+struct test_timedlock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_timed_lock timed_lock_type;
+
+ static bool fake_predicate()
+ {
+ return false;
+ }
+
+ void operator()()
+ {
+ test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
+
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ // Construct and initialize an xtime for a fast time out.
+ boost::system_time xt = boost::get_system_time()+boost::posix_time::milliseconds(100);
+
+ timed_lock_type lock(mutex, xt);
+ BOOST_CHECK(lock ? true : false);
+ }
+ {
+ timed_lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ timed_lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct and initialize an xtime for a fast time out.
+ boost::system_time timeout = boost::get_system_time()+boost::posix_time::milliseconds(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, timeout, fake_predicate));
+ BOOST_CHECK(lock ? true : false);
+
+ boost::system_time now=boost::get_system_time();
+ boost::posix_time::milliseconds const timeout_resolution(20);
+ BOOST_CHECK((timeout-timeout_resolution)<now);
+
+ // Test the lock, unlock and timedlock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ boost::system_time target = boost::get_system_time()+boost::posix_time::milliseconds(100);
+ BOOST_CHECK(lock.timed_lock(target));
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+
+ BOOST_CHECK(mutex.timed_lock(boost::posix_time::milliseconds(100)));
+ mutex.unlock();
+
+ BOOST_CHECK(lock.timed_lock(boost::posix_time::milliseconds(100)));
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ }
+};
+
+template <typename M>
+struct test_recursive_lock
+{
+ typedef M mutex_type;
+ typedef sync::unique_lock< mutex_type > lock_type;
+
+ void operator()()
+ {
+ mutex_type mx;
+ lock_type lock1(mx);
+ lock_type lock2(mx);
+ }
+};
+*/
+
+
+void do_test_mutex()
+{
+ test_lock<boost::sync::mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_mutex)
+{
+ timed_test(&do_test_mutex, 3);
+}
+
+void do_test_try_mutex()
+{
+ test_trylock<boost::sync::mutex>()();
+}
+BOOST_AUTO_TEST_CASE(test_try_mutex)
+{
+ timed_test(&do_test_try_mutex, 3);
+}
+
+/*
+void do_test_timed_mutex()
+{
+ test_lock<sync::timed_mutex>()();
+ test_trylock<sync::timed_mutex>()();
+ test_timedlock<sync::timed_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_mutex)
+{
+ timed_test(&do_test_timed_mutex, 3);
+}
+
+void do_test_recursive_mutex()
+{
+ test_lock<boost::recursive_mutex>()();
+ test_recursive_lock<boost::recursive_mutex>()();
+}
+
+void test_recursive_mutex()
+{
+ timed_test(&do_test_recursive_mutex, 3);
+}
+
+void do_test_recursive_try_mutex()
+{
+ test_lock<boost::recursive_try_mutex>()();
+ test_trylock<boost::recursive_try_mutex>()();
+ test_recursive_lock<boost::recursive_try_mutex>()();
+}
+
+void test_recursive_try_mutex()
+{
+ timed_test(&do_test_recursive_try_mutex, 3);
+}
+
+void do_test_recursive_timed_mutex()
+{
+ test_lock<boost::recursive_timed_mutex>()();
+ test_trylock<boost::recursive_timed_mutex>()();
+ test_timedlock<boost::recursive_timed_mutex>()();
+ test_recursive_lock<boost::recursive_timed_mutex>()();
+}
+
+void test_recursive_timed_mutex()
+{
+ timed_test(&do_test_recursive_timed_mutex, 3);
+}
+*/

Copied: trunk/libs/sync/test/run/semaphore_test.cpp (from r85792, trunk/libs/sync/test/semaphore_test.cpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/sync/test/run/semaphore_test.cpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794, copy of r85792, trunk/libs/sync/test/semaphore_test.cpp)
@@ -0,0 +1,113 @@
+// Copyright (C) 2013 Tim Blechmann
+//
+// Distributed under 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)
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/thread.hpp>
+#include <boost/sync/semaphore.hpp>
+
+#include <boost/typeof/typeof.hpp>
+
+BOOST_AUTO_TEST_CASE(test_semaphore_post_wait)
+{
+ boost::sync::semaphore sem(0);
+
+ sem.post();
+ sem.wait();
+}
+
+
+BOOST_AUTO_TEST_CASE(test_semaphore_try_wait)
+{
+ boost::sync::semaphore sem(0);
+
+ BOOST_REQUIRE(!sem.try_wait());
+ sem.post();
+ BOOST_REQUIRE(sem.try_wait());
+}
+
+
+struct semaphore_wait_and_post_test
+{
+ void run()
+ {
+ boost::thread post_thread(boost::bind(&semaphore_wait_and_post_test::wait_and_post, this));
+ sem_.wait();
+ }
+
+ void wait_and_post()
+ {
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ sem_.post();
+ }
+
+ boost::sync::semaphore sem_;
+ boost::thread thread_;
+};
+
+BOOST_AUTO_TEST_CASE(semaphore_wait_and_post)
+{
+ semaphore_wait_and_post_test test;
+ test.run();
+}
+
+#ifdef BOOST_SYNC_USES_CHRONO
+
+BOOST_AUTO_TEST_CASE(test_semaphore_wait_for)
+{
+ using namespace boost;
+
+ sync::semaphore sem(0);
+
+ BOOST_AUTO(start, chrono::system_clock::now());
+
+ BOOST_REQUIRE(!sem.try_wait_for(chrono::milliseconds(500)));
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+ BOOST_AUTO(wait_time, end - start);
+
+ // guessing!
+ BOOST_REQUIRE( wait_time > chrono::milliseconds(450) );
+ BOOST_REQUIRE( wait_time < chrono::milliseconds(1000) );
+
+ sem.post();
+
+ BOOST_REQUIRE(sem.try_wait_for(chrono::milliseconds(500)));
+}
+
+BOOST_AUTO_TEST_CASE(test_semaphore_wait_until)
+{
+ using namespace boost;
+
+ sync::semaphore sem(0);
+ {
+ BOOST_AUTO(now, chrono::system_clock::now());
+ BOOST_AUTO(timeout, now + chrono::milliseconds(500));
+
+ BOOST_REQUIRE(!sem.try_wait_until(timeout));
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+ BOOST_AUTO(timeout_delta, end - timeout);
+
+ // guessing!
+ BOOST_REQUIRE( timeout_delta > chrono::milliseconds(-400) );
+ BOOST_REQUIRE( timeout_delta < chrono::milliseconds(400) );
+ }
+
+ sem.post();
+
+ {
+ BOOST_AUTO(start, chrono::system_clock::now());
+ BOOST_AUTO(timeout, start + chrono::milliseconds(500));
+
+ BOOST_REQUIRE(sem.try_wait_until(timeout));
+
+ BOOST_AUTO(end, chrono::system_clock::now());
+
+ // guessing!
+ BOOST_REQUIRE( (end - start) < chrono::milliseconds(100) );
+ }
+}
+#endif

Added: trunk/libs/sync/test/run/utils.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/sync/test/run/utils.hpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85794)
@@ -0,0 +1,223 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+// Distributed under 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)
+
+#if !defined(UTIL_INL_WEK01242003)
+#define UTIL_INL_WEK01242003
+
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+
+#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
+# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
+#endif
+
+// boostinspect:nounnamed
+
+
+
+namespace
+{
+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;
+ if (boost::TIME_UTC_ != boost::xtime_get (&xt, boost::TIME_UTC_))
+ BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC_");
+
+ 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;
+}
+
+}
+namespace boost
+{
+namespace threads
+{
+namespace test
+{
+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);
+}
+}
+}
+}
+
+
+namespace
+{
+class execution_monitor
+{
+public:
+ enum wait_type { use_sleep_only, use_mutex, use_condition };
+
+ execution_monitor(wait_type type, int secs)
+ : done(false), type(type), secs(secs) { }
+ void start()
+ {
+ if (type != use_sleep_only) {
+ boost::unique_lock<boost::mutex> lock(mutex); done = false;
+ } else {
+ done = false;
+ }
+ }
+ void finish()
+ {
+ if (type != use_sleep_only) {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ done = true;
+ if (type == use_condition)
+ cond.notify_one();
+ } else {
+ done = true;
+ }
+ }
+ bool wait()
+ {
+ boost::xtime xt = delay(secs);
+ if (type != use_condition)
+ boost::thread::sleep(xt);
+ if (type != use_sleep_only) {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while (type == use_condition && !done) {
+ if (!cond.timed_wait(lock, xt))
+ break;
+ }
+ return done;
+ }
+ return done;
+ }
+
+private:
+ boost::mutex mutex;
+ boost::condition cond;
+ bool done;
+ wait_type type;
+ int secs;
+};
+}
+namespace thread_detail_anon
+{
+template <typename F>
+class indirect_adapter
+{
+public:
+ indirect_adapter(F func, execution_monitor& monitor)
+ : func(func), monitor(monitor) { }
+ void operator()() const
+ {
+ try
+ {
+ boost::thread thrd(func);
+ thrd.join();
+ }
+ catch (...)
+ {
+ monitor.finish();
+ throw;
+ }
+ monitor.finish();
+ }
+
+private:
+ F func;
+ execution_monitor& monitor;
+ void operator=(indirect_adapter&);
+};
+
+}
+// boostinspect:nounnamed
+namespace
+{
+
+template <typename F>
+void timed_test(F func, int secs,
+ execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
+{
+ execution_monitor monitor(type, secs);
+ thread_detail_anon::indirect_adapter<F> ifunc(func, monitor);
+ monitor.start();
+ boost::thread thrd(ifunc);
+ BOOST_REQUIRE_MESSAGE(monitor.wait(),
+ "Timed test didn't complete in time, possible deadlock.");
+}
+
+}
+
+namespace thread_detail_anon
+{
+
+template <typename F, typename T>
+class thread_binder
+{
+public:
+ thread_binder(const F& func, const T& param)
+ : func(func), param(param) { }
+ void operator()() const { func(param); }
+
+private:
+ F func;
+ T param;
+};
+
+}
+
+// boostinspect:nounnamed
+namespace
+{
+template <typename F, typename T>
+thread_detail_anon::thread_binder<F, T> bind(const F& func, const T& param)
+{
+ return thread_detail_anon::thread_binder<F, T>(func, param);
+}
+}
+
+namespace thread_detail_anon
+{
+
+template <typename R, typename T>
+class thread_member_binder
+{
+public:
+ thread_member_binder(R (T::*func)(), T& param)
+ : func(func), param(param) { }
+ void operator()() const { (param.*func)(); }
+
+private:
+ void operator=(thread_member_binder&);
+
+ R (T::*func)();
+ T& param;
+};
+
+}
+
+// boostinspect:nounnamed
+namespace
+{
+template <typename R, typename T>
+thread_detail_anon::thread_member_binder<R, T> bind(R (T::*func)(), T& param)
+{
+ return thread_detail_anon::thread_member_binder<R, T>(func, param);
+}
+} // namespace
+
+#endif

Deleted: trunk/libs/sync/test/semaphore_test.cpp
==============================================================================
--- trunk/libs/sync/test/semaphore_test.cpp 2013-09-19 16:27:08 EDT (Thu, 19 Sep 2013) (r85793)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,113 +0,0 @@
-// Copyright (C) 2013 Tim Blechmann
-//
-// Distributed under 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)
-
-#include <boost/test/unit_test.hpp>
-
-#include <boost/thread.hpp>
-#include <boost/sync/semaphore.hpp>
-
-#include <boost/typeof/typeof.hpp>
-
-BOOST_AUTO_TEST_CASE(test_semaphore_post_wait)
-{
- boost::sync::semaphore sem(0);
-
- sem.post();
- sem.wait();
-}
-
-
-BOOST_AUTO_TEST_CASE(test_semaphore_try_wait)
-{
- boost::sync::semaphore sem(0);
-
- BOOST_REQUIRE(!sem.try_wait());
- sem.post();
- BOOST_REQUIRE(sem.try_wait());
-}
-
-
-struct semaphore_wait_and_post_test
-{
- void run()
- {
- boost::thread post_thread(boost::bind(&semaphore_wait_and_post_test::wait_and_post, this));
- sem_.wait();
- }
-
- void wait_and_post()
- {
- boost::this_thread::sleep_for(boost::chrono::seconds(1));
- sem_.post();
- }
-
- boost::sync::semaphore sem_;
- boost::thread thread_;
-};
-
-BOOST_AUTO_TEST_CASE(semaphore_wait_and_post)
-{
- semaphore_wait_and_post_test test;
- test.run();
-}
-
-#ifdef BOOST_SYNC_USES_CHRONO
-
-BOOST_AUTO_TEST_CASE(test_semaphore_wait_for)
-{
- using namespace boost;
-
- sync::semaphore sem(0);
-
- BOOST_AUTO(start, chrono::system_clock::now());
-
- BOOST_REQUIRE(!sem.try_wait_for(chrono::milliseconds(500)));
-
- BOOST_AUTO(end, chrono::system_clock::now());
- BOOST_AUTO(wait_time, end - start);
-
- // guessing!
- BOOST_REQUIRE( wait_time > chrono::milliseconds(450) );
- BOOST_REQUIRE( wait_time < chrono::milliseconds(1000) );
-
- sem.post();
-
- BOOST_REQUIRE(sem.try_wait_for(chrono::milliseconds(500)));
-}
-
-BOOST_AUTO_TEST_CASE(test_semaphore_wait_until)
-{
- using namespace boost;
-
- sync::semaphore sem(0);
- {
- BOOST_AUTO(now, chrono::system_clock::now());
- BOOST_AUTO(timeout, now + chrono::milliseconds(500));
-
- BOOST_REQUIRE(!sem.try_wait_until(timeout));
-
- BOOST_AUTO(end, chrono::system_clock::now());
- BOOST_AUTO(timeout_delta, end - timeout);
-
- // guessing!
- BOOST_REQUIRE( timeout_delta > chrono::milliseconds(-400) );
- BOOST_REQUIRE( timeout_delta < chrono::milliseconds(400) );
- }
-
- sem.post();
-
- {
- BOOST_AUTO(start, chrono::system_clock::now());
- BOOST_AUTO(timeout, start + chrono::milliseconds(500));
-
- BOOST_REQUIRE(sem.try_wait_until(timeout));
-
- BOOST_AUTO(end, chrono::system_clock::now());
-
- // guessing!
- BOOST_REQUIRE( (end - start) < chrono::milliseconds(100) );
- }
-}
-#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk