Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81383 - in trunk: boost/thread/detail boost/thread/pthread libs/thread/src/pthread libs/thread/src/win32
From: vicente.botet_at_[hidden]
Date: 2012-11-17 04:00:18


Author: viboes
Date: 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
New Revision: 81383
URL: http://svn.boost.org/trac/boost/changeset/81383

Log:
Thread: Towards removing DateTime dependency on the library binary file.
Text files modified:
   trunk/boost/thread/detail/thread.hpp | 4
   trunk/boost/thread/pthread/condition_variable.hpp | 14 +++--
   trunk/boost/thread/pthread/condition_variable_fwd.hpp | 28 +++++++---
   trunk/boost/thread/pthread/thread_data.hpp | 58 +++++++----------------
   trunk/boost/thread/pthread/timespec.hpp | 97 +++++++++++++++++++++++++++++++++------
   trunk/libs/thread/src/pthread/thread.cpp | 86 +++++++++++++++++++++++++++++++++-
   trunk/libs/thread/src/win32/thread.cpp | 1
   7 files changed, 212 insertions(+), 76 deletions(-)

Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp (original)
+++ trunk/boost/thread/detail/thread.hpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -3,8 +3,8 @@
 // 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)
-// (C) Copyright 2007-10 Anthony Williams
-// (C) Copyright 20011-12 Vicente J. Botet Escriba
+// (C) Copyright 2007-2010 Anthony Williams
+// (C) Copyright 20011-2012 Vicente J. Botet Escriba
 
 #include <boost/thread/detail/config.hpp>
 

Modified: trunk/boost/thread/pthread/condition_variable.hpp
==============================================================================
--- trunk/boost/thread/pthread/condition_variable.hpp (original)
+++ trunk/boost/thread/pthread/condition_variable.hpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -4,7 +4,7 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 // (C) Copyright 2007-10 Anthony Williams
-// (C) Copyright 2011 Vicente J. Botet Escriba
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
 
 #include <boost/thread/pthread/timespec.hpp>
 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
@@ -75,12 +75,14 @@
         }
     }
 
- inline bool condition_variable::do_timed_wait(
+ inline bool condition_variable::do_wait_until(
                 unique_lock<mutex>& m,
                 struct timespec const &timeout)
     {
         if (!m.owns_lock())
- boost::throw_exception(condition_error(EPERM, "condition_variable do_timed_wait: mutex not locked"));
+ {
+ boost::throw_exception(condition_error(EPERM, "condition_variable do_wait_until: mutex not locked"));
+ }
 
         thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
         int cond_res;
@@ -176,7 +178,7 @@
         bool timed_wait(lock_type& m,boost::system_time const& wait_until)
         {
             struct timespec const timeout=detail::to_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ return do_wait_until(m, timeout);
         }
         template<typename lock_type>
         bool timed_wait(lock_type& m,xtime const& wait_until)
@@ -296,7 +298,7 @@
             using namespace chrono;
             nanoseconds d = tp.time_since_epoch();
             timespec ts = boost::detail::to_timespec(d);
- if (do_timed_wait(lk, ts)) return cv_status::no_timeout;
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
             else return cv_status::timeout;
         }
 #endif
@@ -315,7 +317,7 @@
     private: // used by boost::thread::try_join_until
 
         template <class lock_type>
- inline bool do_timed_wait(
+ inline bool do_wait_until(
           lock_type& m,
           struct timespec const &timeout)
         {

Modified: trunk/boost/thread/pthread/condition_variable_fwd.hpp
==============================================================================
--- trunk/boost/thread/pthread/condition_variable_fwd.hpp (original)
+++ trunk/boost/thread/pthread/condition_variable_fwd.hpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -4,7 +4,7 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 // (C) Copyright 2007-8 Anthony Williams
-// (C) Copyright 2011 Vicente J. Botet Escriba
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
 
 #include <boost/assert.hpp>
 #include <boost/throw_exception.hpp>
@@ -13,6 +13,7 @@
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/lock_types.hpp>
 #include <boost/thread/thread_time.hpp>
+#include <boost/thread/pthread/timespec.hpp>
 #include <boost/thread/xtime.hpp>
 #ifdef BOOST_THREAD_USES_CHRONO
 #include <boost/chrono/system_clocks.hpp>
@@ -32,6 +33,20 @@
         pthread_cond_t cond;
 
     public:
+ //private: // used by boost::thread::try_join_until
+
+ inline bool do_wait_until(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout);
+
+ bool do_wait_for(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout)
+ {
+ return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
+ }
+
+ public:
       BOOST_THREAD_NO_COPYABLE(condition_variable)
         condition_variable()
         {
@@ -73,10 +88,10 @@
         {
 #if defined BOOST_THREAD_WAIT_BUG
             struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
- return do_timed_wait(m, timeout);
+ return do_wait_until(m, timeout);
 #else
             struct timespec const timeout=detail::to_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ return do_wait_until(m, timeout);
 #endif
         }
         bool timed_wait(
@@ -219,15 +234,10 @@
             using namespace chrono;
             nanoseconds d = tp.time_since_epoch();
             timespec ts = boost::detail::to_timespec(d);
- if (do_timed_wait(lk, ts)) return cv_status::no_timeout;
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
             else return cv_status::timeout;
         }
 #endif
- //private: // used by boost::thread::try_join_until
-
- inline bool do_timed_wait(
- unique_lock<mutex>& lock,
- struct timespec const &timeout);
     };
 
     BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);

Modified: trunk/boost/thread/pthread/thread_data.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread_data.hpp (original)
+++ trunk/boost/thread/pthread/thread_data.hpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -210,65 +210,43 @@
 
     namespace this_thread
     {
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts);
+ }
+
 #ifdef BOOST_THREAD_USES_CHRONO
         inline
         void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
         {
- using namespace chrono;
- boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
-
- if(thread_info)
- {
- unique_lock<mutex> lk(thread_info->sleep_mutex);
- while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {}
- }
- else
- {
- if (ns >= nanoseconds::zero())
- {
-
- # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
- timespec ts = boost::detail::to_timespec(ns);
- BOOST_VERIFY(!pthread_delay_np(&ts));
- # elif defined(BOOST_HAS_NANOSLEEP)
- timespec ts = boost::detail::to_timespec(ns);
- // nanosleep takes a timespec that is an offset, not
- // an absolute time.
- nanosleep(&ts, 0);
- # else
- mutex mx;
- unique_lock<mutex> lock(mx);
- condition_variable cond;
- cond.wait_for(lock, ns);
- # endif
- }
- }
+ return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns));
         }
-#endif
+#endif // BOOST_THREAD_USES_CHRONO
+
         void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
 
 #if defined BOOST_THREAD_USES_DATETIME
 #ifdef __DECXXX
         /// Workaround of DECCXX issue of incorrect template substitution
- template<typename TimeDuration>
- inline void sleep(TimeDuration const& rel_time)
- {
- this_thread::sleep(get_system_time()+rel_time);
- }
-
         template<>
+#endif
         void BOOST_THREAD_DECL sleep(system_time const& abs_time)
+#if 1
+ ;
 #else
- void BOOST_THREAD_DECL sleep(system_time const& abs_time);
+ {
+ return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
+ }
+#endif
 
         template<typename TimeDuration>
         inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
         {
             this_thread::sleep(get_system_time()+rel_time);
         }
-#endif
-#endif
- }
+#endif // BOOST_THREAD_USES_DATETIME
+ } // this_thread
 }
 
 #include <boost/config/abi_suffix.hpp>

Modified: trunk/boost/thread/pthread/timespec.hpp
==============================================================================
--- trunk/boost/thread/pthread/timespec.hpp (original)
+++ trunk/boost/thread/pthread/timespec.hpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -1,6 +1,7 @@
 #ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
 #define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
 // (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -19,33 +20,99 @@
 #include <boost/chrono/duration.hpp>
 #endif
 
+#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define BOOST_THREAD_TIMESPEC_MAC_API
+#include <sys/time.h> //for gettimeofday and timeval
+#else
+#include <time.h> // for clock_gettime
+#endif
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
- namespace detail
- {
+ namespace detail
+ {
 #if defined BOOST_THREAD_USES_DATETIME
- inline struct timespec to_timespec(boost::system_time const& abs_time)
- {
- struct timespec timeout={0,0};
- boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+ inline struct timespec to_timespec(boost::system_time const& abs_time)
+ {
+ struct timespec timeout = { 0,0};
+ boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
 
- timeout.tv_sec=time_since_epoch.total_seconds();
- timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
- return timeout;
- }
+ timeout.tv_sec=time_since_epoch.total_seconds();
+ timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
+ return timeout;
+ }
 #endif
 #if defined BOOST_THREAD_USES_CHRONO
- inline timespec to_timespec(chrono::nanoseconds const& ns)
+ inline timespec to_timespec(chrono::nanoseconds const& ns)
+ {
+ struct timespec ts;
+ ts.tv_sec = static_cast<long>(chrono::duration_cast<chrono::seconds>(ns).count());
+ ts.tv_nsec = static_cast<long>((ns - chrono::duration_cast<chrono::seconds>(ns)).count());
+ return ts;
+ }
+
+#endif
+
+ inline timespec to_timespec(boost::intmax_t const& ns)
+ {
+ boost::intmax_t s = ns / 1000000000l;
+ struct timespec ts;
+ ts.tv_sec = static_cast<long> (s);
+ ts.tv_nsec = static_cast<long> (ns - s * 1000000000l);
+ return ts;
+ }
+ inline boost::intmax_t to_nanoseconds_int_max(timespec const& ts)
+ {
+ return ts.tv_sec * 1000000000l + ts.tv_nsec;
+ }
+ inline bool timespec_ge_zero(timespec const& ts)
+ {
+ return (ts.tv_sec >= 0) || (ts.tv_nsec >= 0);
+ }
+ inline timespec timespec_now()
+ {
+ timespec ts;
+
+#if defined(BOOST_THREAD_TIMESPEC_MAC_API)
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+#else
+ if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
       {
- struct timespec ts;
- ts.tv_sec = static_cast<long>(no::duration_cast<chrono::seconds>(ns).count());
- ts.tv_nsec = static_cast<long>((ns - no::duration_cast<chrono::seconds>(ns)).count());
- return ts;
+ BOOST_ASSERT(0 && "Boost::Thread - Internal Error");
       }
 #endif
+ return ts;
+ }
+ inline timespec timespec_zero()
+ {
+ timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ return ts;
+ }
+ inline timespec timespec_plus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) + to_nanoseconds_int_max(rhs));
     }
+ inline timespec timespec_minus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) - to_nanoseconds_int_max(rhs));
+ }
+ inline bool timespec_gt(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) > to_nanoseconds_int_max(rhs);
+ }
+ inline bool timespec_ge(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) >= to_nanoseconds_int_max(rhs);
+ }
+
+ }
 }
 
 #include <boost/config/abi_suffix.hpp>

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp (original)
+++ trunk/libs/thread/src/pthread/thread.cpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -1,7 +1,7 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
 // Copyright (C) 2007-8 Anthony Williams
-// (C) Copyright 2011 Vicente J. Botet Escriba
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
 //
 // 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)
@@ -351,7 +351,7 @@
                 unique_lock<mutex> lock(local_thread_info->data_mutex);
                 while(!local_thread_info->done)
                 {
- if(!local_thread_info->done_condition.do_timed_wait(lock,timeout))
+ if(!local_thread_info->done_condition.do_wait_until(lock,timeout))
                     {
                       res=false;
                       return true;
@@ -418,11 +418,88 @@
 
     namespace this_thread
     {
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts)
+ {
+ boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
 
+ if(thread_info)
+ {
+ unique_lock<mutex> lk(thread_info->sleep_mutex);
+ while( thread_info->sleep_condition.do_wait_for(lk,ts)) {}
+ }
+ else
+ {
+
+ if (boost::detail::timespec_ge(ts, boost::detail::timespec_zero()))
+ {
+
+ # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+ BOOST_VERIFY(!pthread_delay_np(&ts));
+ # elif defined(BOOST_HAS_NANOSLEEP)
+ // nanosleep takes a timespec that is an offset, not
+ // an absolute time.
+ nanosleep(&ts, 0);
+ # else
+ mutex mx;
+ unique_lock<mutex> lock(mx);
+ condition_variable cond;
+ cond.do_wait_for(lock, ts);
+ # endif
+ }
+ }
+ }
+
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts)
+ {
+ boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
+
+ if(thread_info)
+ {
+ unique_lock<mutex> lk(thread_info->sleep_mutex);
+ while(thread_info->sleep_condition.do_wait_until(lk,ts)) {}
+ }
+ else
+ {
+ timespec now = boost::detail::timespec_now();
+ if (boost::detail::timespec_gt(ts, now))
+ {
+ for (int foo=0; foo < 5; ++foo)
+ {
+
+ # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+ timespec d = boost::detail::timespec_minus(ts, now);
+ BOOST_VERIFY(!pthread_delay_np(&d));
+ # elif defined(BOOST_HAS_NANOSLEEP)
+ // nanosleep takes a timespec that is an offset, not
+ // an absolute time.
+ timespec d = boost::detail::timespec_minus(ts, now);
+ nanosleep(&d, 0);
+ # else
+ mutex mx;
+ unique_lock<mutex> lock(mx);
+ condition_variable cond;
+ cond.do_wait_until(lock, ts);
+ # endif
+ timespec now2 = boost::detail::timespec_now();
+ if (boost::detail::timespec_ge(now2, ts))
+ {
+ return;
+ }
+ }
+ }
+ }
+ }
+ } // hiden
+ } // this_thread
+ namespace this_thread
+ {
+#if 1
 #ifdef __DECXXX
         /// Workaround of DECCXX issue of incorrect template substitution
         template<>
-#endif
+#endif // __DECXXX
 #if defined BOOST_THREAD_USES_DATETIME
         void sleep(const system_time& st)
         {
@@ -463,7 +540,8 @@
                 }
             }
         }
-#endif
+#endif // BOOST_THREAD_USES_DATETIME
+#endif //1
         void yield() BOOST_NOEXCEPT
         {
 # if defined(BOOST_HAS_SCHED_YIELD)

Modified: trunk/libs/thread/src/win32/thread.cpp
==============================================================================
--- trunk/libs/thread/src/win32/thread.cpp (original)
+++ trunk/libs/thread/src/win32/thread.cpp 2012-11-17 04:00:16 EST (Sat, 17 Nov 2012)
@@ -3,6 +3,7 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 // (C) Copyright 2007 Anthony Williams
 // (C) Copyright 2007 David Deakins
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
 
 #ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x400


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