Skip to content

Commit

Permalink
make condition_variable_any steady when BOOST_THREAD_HAS_CONDATTR_SET…
Browse files Browse the repository at this point in the history
…_CLOCK_MONOTONIC.
  • Loading branch information
viboes committed Sep 25, 2015
1 parent 0fdd4fc commit 8f5de1d
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 64 deletions.
121 changes: 86 additions & 35 deletions include/boost/thread/pthread/condition_variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ namespace boost
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
int const res2=pthread_cond_init(&cond,NULL);
int const res2 = detail::monotonic_pthread_cond_init(cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
}
}
~condition_variable_any()
Expand Down Expand Up @@ -240,6 +240,8 @@ namespace boost
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
Expand Down Expand Up @@ -268,22 +270,6 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}

template <class lock_type, class Clock, class Duration, class Predicate>
bool
wait_until(
lock_type& lock,
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
}
return true;
}


template <class lock_type, class Rep, class Period>
cv_status
wait_for(
Expand All @@ -299,35 +285,100 @@ namespace boost

}

template <class lock_type>
cv_status wait_until(
lock_type& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO

template <class lock_type, class Rep, class Period, class Predicate>
bool
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d,
Predicate pred)
template <class lock_type, class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<chrono::steady_clock, Duration>& t)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
using namespace chrono;
typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return steady_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
}

template <class lock_type, class Clock, class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
steady_clock::time_point s_now = steady_clock::now();
typename Clock::time_point c_now = Clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}

// while (!pred())
// {
// if (wait_for(lock, d) == cv_status::timeout)
// return pred();
// }
// return true;
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, c_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}

template <class lock_type>
cv_status wait_until(
lock_type& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}

#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Clock, class Duration, class Predicate>
bool
wait_until(
lock_type& lock,
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
}
return true;
}

template <class lock_type, class Rep, class Period, class Predicate>
bool
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif

void notify_one() BOOST_NOEXCEPT
Expand Down
55 changes: 26 additions & 29 deletions include/boost/thread/pthread/condition_variable_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@

namespace boost
{
namespace detail {
inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {

#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
res=pthread_cond_init(&cond,&attr);
pthread_condattr_destroy(&attr);
return res;
#else
return pthread_cond_init(&cond,NULL);
#endif

}
}

class condition_variable
{
Expand Down Expand Up @@ -56,35 +76,19 @@ namespace boost
condition_variable()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
int const res=pthread_mutex_init(&internal_mutex,NULL);
int res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
#endif

#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
pthread_condattr_t attr;
int res2 = pthread_condattr_init(&attr);
if(res2)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_steady::condition_variable_steady() constructor failed in pthread_condattr_init"));
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
res2=pthread_cond_init(&cond,&attr);
pthread_condattr_destroy(&attr);
#else
int const res2=pthread_cond_init(&cond,NULL);
#endif
if(res2)
res = detail::monotonic_pthread_cond_init(cond);
if (res)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
}
}
~condition_variable()
Expand Down Expand Up @@ -249,7 +253,7 @@ namespace boost
}
#endif

#else
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO

template <class Duration>
Expand Down Expand Up @@ -304,7 +308,7 @@ namespace boost
}
#endif

#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration, class Predicate>
Expand All @@ -330,13 +334,6 @@ namespace boost
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));

// while (!pred())
// {
// if (wait_for(lock, d) == cv_status::timeout)
// return pred();
// }
// return true;
}
#endif

Expand Down

0 comments on commit 8f5de1d

Please sign in to comment.