[Boost-bugs] [Boost C++ Libraries] #7800: this_thread::sleep_for for pthread environment with BOOST_THREAD_USES_CHRONO may wait repeatedly

Subject: [Boost-bugs] [Boost C++ Libraries] #7800: this_thread::sleep_for for pthread environment with BOOST_THREAD_USES_CHRONO may wait repeatedly
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-12-17 17:01:56


#7800: this_thread::sleep_for for pthread environment with
BOOST_THREAD_USES_CHRONO may wait repeatedly
-------------------------------------+--------------------------------------
 Reporter: atara-y@… | Owner: anthonyw
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: thread
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
-------------------------------------+--------------------------------------
 In 1.52 implementation for pthread environment, with
 BOOST_THREAD_USES_CHRONO,
 * this_thread::sleep_for(boost::chrono::seconds(n)) calls:
 * template <class Rep, class Period> void sleep_for(const
 chrono::duration<Rep, Period>& d) in boost/thread/v2/thread.hpp, which
 calls:
 * void sleep_for(const chrono::nanoseconds& ns) in
 boost/thread/pthread/thread_data.hpp, which calls:
 {{{
 #!cpp
         template <class Rep, class Period>
         cv_status
         wait_for(
                 unique_lock<mutex>& lock,
                 const chrono::duration<Rep, Period>& d)
         {
           using namespace chrono;
           system_clock::time_point s_now = system_clock::now();
           steady_clock::time_point c_now = steady_clock::now();
           wait_until(lock, s_now + ceil<nanoseconds>(d));
           return steady_clock::now() - c_now < d ? cv_status::no_timeout :
                                                    cv_status::timeout;

         }
 }}}
 in boost/thread/pthread/condition_variable_fwd.hpp.
 This function can return cv_status::no_timeout, even if
 steady_cloke::now() - c_now is nearly equal to d.
 At the caller side, this function is used in loop condition:

 {{{
 #!cpp
 while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns))
 {}
 }}}

 ''ns'' is wait period and not touched in this statement. So, it tries to
 wait the same period again.

 This behavior can be observable in FreeBSD 8.3-STABLE and Cygwin for Boost
 1.52.

 In trunk r82046, call graph and implementation have been changed.
 If BOOST_THREAD_SLEEP_FOR_IS_STEADY is defined,
 * this_thread::sleep_for(boost::chrono::seconds(n)) calls:
 * template <class Rep, class Period> void sleep_for(const
 chrono::duration<Rep, Period>& d) in boost/thread/v2/thread.hpp, which
 calls:
 * void sleep_for(const chrono::nanoseconds& ns) in
 boost/thread/pthread/thread_data.hpp, which calls:
 * void sleep_for(const timespec& ts) in
 libs/thread/src/pthread/thread.cpp, which calls:
 * bool do_wait_for(unique_lock<mutex>& lock, struct timespec const
 &timeout) in boost/thread/pthread/condition_variable_fwd.hpp, which calls:
 * bool do_wait_until(unique_lock<mutex>& m, struct timespec const
 &timeout) in boost/thread/pthread/condition_variable.hpp, which calls
 * pthread_cond_timedwait.

 If pthread_cond_timedwait returns ETIMEDOUT, the following loop in void
 sleep_for(const timespec& ts) exits. So, there is no problem.


 {{{
 #!cpp
     while( thread_info->sleep_condition.do_wait_for(lk,ts)) {}
 }}}

 BOOST_HAS_NANOSLEEP is defined for both of FreeBSD and Cygwin. As a
 result, BOOST_THREAD_SLEEP_FOR_IS_STEADY is defined. Therefore, problems
 for the environment has been resolved.
 However, if BOOST_THREAD_SLEEP_FOR_IS_STEADY is not defined,
 * this_thread::sleep_for(boost::chrono::seconds(n)) calls:

 {{{
 #!cpp
     template <class Rep, class Period>
     void sleep_for(const chrono::duration<Rep, Period>& d)
     {
       using namespace chrono;
       if (d > duration<Rep, Period>::zero())
       {
         steady_clock::time_point c_now = steady_clock::now();
         do
         {
           sleep_until(system_clock::now() + ceil<nanoseconds>(d));
         } while (steady_clock::now() - c_now < d );
       }
     }
 }}}

 in boost/thread/v2/thread.hpp.
 The similar analysis for 1.52 can be applied on the above function. It may
 wait ''d'' period again.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/7800>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC