summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/__mutex_base32
-rw-r--r--libcxx/include/thread18
-rw-r--r--libcxx/src/condition_variable.cpp16
-rw-r--r--libcxx/src/thread.cpp18
4 files changed, 53 insertions, 31 deletions
diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base
index 4fdcb617fbc..1782e7c0b39 100644
--- a/libcxx/include/__mutex_base
+++ b/libcxx/include/__mutex_base
@@ -323,11 +323,6 @@ public:
template <class _Predicate>
void wait(unique_lock<mutex>& __lk, _Predicate __pred);
- template <class _Duration>
- cv_status
- wait_until(unique_lock<mutex>& __lk,
- const chrono::time_point<chrono::system_clock, _Duration>& __t);
-
template <class _Clock, class _Duration>
cv_status
wait_until(unique_lock<mutex>& __lk,
@@ -382,28 +377,13 @@ condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
wait(__lk);
}
-template <class _Duration>
-cv_status
-condition_variable::wait_until(unique_lock<mutex>& __lk,
- const chrono::time_point<chrono::system_clock, _Duration>& __t)
-{
- using namespace chrono;
- typedef time_point<system_clock, nanoseconds> __nano_sys_tmpt;
- __do_timed_wait(__lk,
- __nano_sys_tmpt(__ceil<nanoseconds>(__t.time_since_epoch())));
- return system_clock::now() < __t ? cv_status::no_timeout :
- cv_status::timeout;
-}
-
template <class _Clock, class _Duration>
cv_status
condition_variable::wait_until(unique_lock<mutex>& __lk,
const chrono::time_point<_Clock, _Duration>& __t)
{
using namespace chrono;
- system_clock::time_point __s_now = system_clock::now();
- typename _Clock::time_point __c_now = _Clock::now();
- __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__t - __c_now));
+ wait_for(__lk, __t - _Clock::now());
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
}
@@ -427,9 +407,17 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
const chrono::duration<_Rep, _Period>& __d)
{
using namespace chrono;
+ if (__d <= __d.zero())
+ return cv_status::timeout;
+ typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
+ typedef time_point<system_clock, nanoseconds> __sys_tpi;
+ __sys_tpf _Max = __sys_tpi::max();
system_clock::time_point __s_now = system_clock::now();
steady_clock::time_point __c_now = steady_clock::now();
- __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
+ if (_Max - __d > __s_now)
+ __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
+ else
+ __do_timed_wait(__lk, __sys_tpi::max());
return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
cv_status::timeout;
}
diff --git a/libcxx/include/thread b/libcxx/include/thread
index d81e8537888..94e7ab6c54c 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -410,10 +410,20 @@ void
sleep_for(const chrono::duration<_Rep, _Period>& __d)
{
using namespace chrono;
- nanoseconds __ns = duration_cast<nanoseconds>(__d);
- if (__ns < __d)
- ++__ns;
- sleep_for(__ns);
+ if (__d > duration<_Rep, _Period>::zero())
+ {
+ _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+ nanoseconds __ns;
+ if (__d < _Max)
+ {
+ __ns = duration_cast<nanoseconds>(__d);
+ if (__ns < __d)
+ ++__ns;
+ }
+ else
+ __ns = nanoseconds::max();
+ sleep_for(__ns);
+ }
}
template <class _Clock, class _Duration>
diff --git a/libcxx/src/condition_variable.cpp b/libcxx/src/condition_variable.cpp
index 552bce3561d..de0f6f47dd1 100644
--- a/libcxx/src/condition_variable.cpp
+++ b/libcxx/src/condition_variable.cpp
@@ -51,10 +51,22 @@ condition_variable::__do_timed_wait(unique_lock<mutex>& lk,
__throw_system_error(EPERM,
"condition_variable::timed wait: mutex not locked");
nanoseconds d = tp.time_since_epoch();
+ if (d > nanoseconds(0x59682F000000E941))
+ d = nanoseconds(0x59682F000000E941);
timespec ts;
seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<decltype(ts.tv_sec)>(s.count());
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count());
+ typedef decltype(ts.tv_sec) ts_sec;
+ _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();
+ if (s.count() < ts_sec_max)
+ {
+ ts.tv_sec = static_cast<ts_sec>(s.count());
+ ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count());
+ }
+ else
+ {
+ ts.tv_sec = ts_sec_max;
+ ts.tv_nsec = giga::num - 1;
+ }
int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);
if (ec != 0 && ec != ETIMEDOUT)
__throw_system_error(ec, "condition_variable timed_wait failed");
diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp
index 4445b8dbb9c..8747adf0b59 100644
--- a/libcxx/src/thread.cpp
+++ b/libcxx/src/thread.cpp
@@ -11,6 +11,7 @@
#include "exception"
#include "vector"
#include "future"
+#include "limits"
#include <sys/types.h>
#if !_WIN32
#if !__sun__ && !__linux__
@@ -83,11 +84,22 @@ void
sleep_for(const chrono::nanoseconds& ns)
{
using namespace chrono;
- if (ns >= nanoseconds::zero())
+ if (ns > nanoseconds::zero())
{
+ seconds s = duration_cast<seconds>(ns);
timespec ts;
- ts.tv_sec = static_cast<decltype(ts.tv_sec)>(duration_cast<seconds>(ns).count());
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns - seconds(ts.tv_sec)).count());
+ typedef decltype(ts.tv_sec) ts_sec;
+ _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();
+ if (s.count() < ts_sec_max)
+ {
+ ts.tv_sec = static_cast<ts_sec>(s.count());
+ ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count());
+ }
+ else
+ {
+ ts.tv_sec = ts_sec_max;
+ ts.tv_nsec = giga::num - 1;
+ }
nanosleep(&ts, 0);
}
}
OpenPOWER on IntegriCloud