$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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