Skip to content

Commit c1c519d

Browse files
committed
Revert "Implement std::condition_variable via pthread_cond_clockwait() where available"
This reverts commit 5e37d7f. llvm-svn: 372034
1 parent 474c713 commit c1c519d

File tree

3 files changed

+28
-156
lines changed

3 files changed

+28
-156
lines changed

libcxx/include/__config

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,12 +1087,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
10871087
# endif // _LIBCPP_HAS_THREAD_API
10881088
#endif // _LIBCPP_HAS_NO_THREADS
10891089

1090-
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
1091-
# if (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)
1092-
# define _LIBCPP_HAS_COND_CLOCKWAIT
1093-
# endif
1094-
#endif
1095-
10961090
#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
10971091
#error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \
10981092
_LIBCPP_HAS_NO_THREADS is not defined.

libcxx/include/__mutex_base

Lines changed: 17 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <system_error>
1616
#include <__threading_support>
1717

18-
#include <time.h>
1918

2019
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2120
#pragma GCC system_header
@@ -338,75 +337,23 @@ public:
338337
private:
339338
void __do_timed_wait(unique_lock<mutex>& __lk,
340339
chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
341-
#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
342-
void __do_timed_wait(unique_lock<mutex>& __lk,
343-
chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
344-
#endif
345-
template <class _Clock>
346-
void __do_timed_wait(unique_lock<mutex>& __lk,
347-
chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
348340
};
349341
#endif // !_LIBCPP_HAS_NO_THREADS
350342

351-
template <class _Rep, class _Period>
343+
template <class _To, class _Rep, class _Period>
352344
inline _LIBCPP_INLINE_VISIBILITY
353345
typename enable_if
354346
<
355-
is_floating_point<_Rep>::value,
356-
chrono::nanoseconds
347+
chrono::__is_duration<_To>::value,
348+
_To
357349
>::type
358-
__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
350+
__ceil(chrono::duration<_Rep, _Period> __d)
359351
{
360352
using namespace chrono;
361-
using __ratio = ratio_divide<_Period, nano>;
362-
using __ns_rep = nanoseconds::rep;
363-
_Rep __result_float = __d.count() * __ratio::num / __ratio::den;
364-
365-
_Rep __result_max = numeric_limits<__ns_rep>::max();
366-
if (__result_float >= __result_max) {
367-
return nanoseconds::max();
368-
}
369-
370-
_Rep __result_min = numeric_limits<__ns_rep>::min();
371-
if (__result_float <= __result_min) {
372-
return nanoseconds::min();
373-
}
374-
375-
return nanoseconds(static_cast<__ns_rep>(__result_float));
376-
}
377-
378-
template <class _Rep, class _Period>
379-
inline _LIBCPP_INLINE_VISIBILITY
380-
typename enable_if
381-
<
382-
!is_floating_point<_Rep>::value,
383-
chrono::nanoseconds
384-
>::type
385-
__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d)
386-
{
387-
using namespace chrono;
388-
if (__d.count() == 0) {
389-
return nanoseconds(0);
390-
}
391-
392-
using __ratio = ratio_divide<_Period, nano>;
393-
using __ns_rep = nanoseconds::rep;
394-
__ns_rep __result_max = std::numeric_limits<__ns_rep>::max();
395-
if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) {
396-
return nanoseconds::max();
397-
}
398-
399-
__ns_rep __result_min = std::numeric_limits<__ns_rep>::min();
400-
if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) {
401-
return nanoseconds::min();
402-
}
403-
404-
__ns_rep __result = __d.count() * __ratio::num / __ratio::den;
405-
if (__result == 0) {
406-
return nanoseconds(1);
407-
}
408-
409-
return nanoseconds(__result);
353+
_To __r = duration_cast<_To>(__d);
354+
if (__r < __d)
355+
++__r;
356+
return __r;
410357
}
411358

412359
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -424,15 +371,7 @@ condition_variable::wait_until(unique_lock<mutex>& __lk,
424371
const chrono::time_point<_Clock, _Duration>& __t)
425372
{
426373
using namespace chrono;
427-
using __clock_tp_ns = time_point<_Clock, nanoseconds>;
428-
429-
typename _Clock::time_point __now = _Clock::now();
430-
if (__t <= __now)
431-
return cv_status::timeout;
432-
433-
__clock_tp_ns __t_ns = __clock_tp_ns(__safe_nanosecond_cast(__t.time_since_epoch()));
434-
435-
__do_timed_wait(__lk, __t_ns);
374+
wait_for(__lk, __t - _Clock::now());
436375
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
437376
}
438377

@@ -458,25 +397,15 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
458397
using namespace chrono;
459398
if (__d <= __d.zero())
460399
return cv_status::timeout;
461-
using __ns_rep = nanoseconds::rep;
400+
typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
401+
typedef time_point<system_clock, nanoseconds> __sys_tpi;
402+
__sys_tpf _Max = __sys_tpi::max();
462403
steady_clock::time_point __c_now = steady_clock::now();
463-
464-
#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
465-
using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
466-
__ns_rep __now_count_ns = __safe_nanosecond_cast(__c_now.time_since_epoch()).count();
467-
#else
468-
using __clock_tp_ns = time_point<system_clock, nanoseconds>;
469-
__ns_rep __now_count_ns = __safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
470-
#endif
471-
472-
__ns_rep __d_ns_count = __safe_nanosecond_cast(__d).count();
473-
474-
if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
475-
__do_timed_wait(__lk, __clock_tp_ns::max());
476-
} else {
477-
__do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
478-
}
479-
404+
system_clock::time_point __s_now = system_clock::now();
405+
if (_Max - __d > __s_now)
406+
__do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
407+
else
408+
__do_timed_wait(__lk, __sys_tpi::max());
480409
return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
481410
cv_status::timeout;
482411
}
@@ -492,46 +421,6 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
492421
_VSTD::move(__pred));
493422
}
494423

495-
#if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
496-
inline
497-
void
498-
condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
499-
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT
500-
{
501-
using namespace chrono;
502-
if (!__lk.owns_lock())
503-
__throw_system_error(EPERM,
504-
"condition_variable::timed wait: mutex not locked");
505-
nanoseconds __d = __tp.time_since_epoch();
506-
timespec __ts;
507-
seconds __s = duration_cast<seconds>(__d);
508-
using __ts_sec = decltype(__ts.tv_sec);
509-
const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
510-
if (__s.count() < __ts_sec_max)
511-
{
512-
__ts.tv_sec = static_cast<__ts_sec>(__s.count());
513-
__ts.tv_nsec = (__d - __s).count();
514-
}
515-
else
516-
{
517-
__ts.tv_sec = __ts_sec_max;
518-
__ts.tv_nsec = giga::num - 1;
519-
}
520-
int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts);
521-
if (__ec != 0 && __ec != ETIMEDOUT)
522-
__throw_system_error(__ec, "condition_variable timed_wait failed");
523-
}
524-
#endif // _LIBCPP_HAS_COND_CLOCKWAIT
525-
526-
template <class _Clock>
527-
inline
528-
void
529-
condition_variable::__do_timed_wait(unique_lock<mutex>& __lk,
530-
chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT
531-
{
532-
wait_for(__lk, __tp - _Clock::now());
533-
}
534-
535424
#endif // !_LIBCPP_HAS_NO_THREADS
536425

537426
_LIBCPP_END_NAMESPACE_STD

libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525

2626
#include "test_macros.h"
2727

28-
struct TestClock
28+
struct Clock
2929
{
3030
typedef std::chrono::milliseconds duration;
3131
typedef duration::rep rep;
3232
typedef duration::period period;
33-
typedef std::chrono::time_point<TestClock> time_point;
33+
typedef std::chrono::time_point<Clock> time_point;
3434
static const bool is_steady = true;
3535

3636
static time_point now()
@@ -50,40 +50,35 @@ int test2 = 0;
5050

5151
int runs = 0;
5252

53-
template <typename Clock>
5453
void f()
5554
{
5655
std::unique_lock<std::mutex> lk(mut);
5756
assert(test2 == 0);
5857
test1 = 1;
5958
cv.notify_one();
60-
typename Clock::time_point t0 = Clock::now();
61-
typename Clock::time_point t = t0 + std::chrono::milliseconds(250);
59+
Clock::time_point t0 = Clock::now();
60+
Clock::time_point t = t0 + Clock::duration(250);
6261
while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout)
6362
;
64-
typename Clock::time_point t1 = Clock::now();
63+
Clock::time_point t1 = Clock::now();
6564
if (runs == 0)
6665
{
67-
assert(t1 - t0 < std::chrono::milliseconds(250));
66+
assert(t1 - t0 < Clock::duration(250));
6867
assert(test2 != 0);
6968
}
7069
else
7170
{
72-
assert(t1 - t0 - std::chrono::milliseconds(250) < std::chrono::milliseconds(50));
71+
assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
7372
assert(test2 == 0);
7473
}
7574
++runs;
7675
}
7776

78-
template <typename Clock>
79-
void run_test()
77+
int main(int, char**)
8078
{
81-
runs = 0;
82-
test1 = 0;
83-
test2 = 0;
8479
{
8580
std::unique_lock<std::mutex>lk(mut);
86-
std::thread t(f<Clock>);
81+
std::thread t(f);
8782
assert(test1 == 0);
8883
while (test1 == 0)
8984
cv.wait(lk);
@@ -97,20 +92,14 @@ void run_test()
9792
test2 = 0;
9893
{
9994
std::unique_lock<std::mutex>lk(mut);
100-
std::thread t(f<Clock>);
95+
std::thread t(f);
10196
assert(test1 == 0);
10297
while (test1 == 0)
10398
cv.wait(lk);
10499
assert(test1 != 0);
105100
lk.unlock();
106101
t.join();
107102
}
108-
}
109103

110-
int main(int, char**)
111-
{
112-
run_test<TestClock>();
113-
run_test<std::chrono::steady_clock>();
114-
run_test<std::chrono::system_clock>();
115-
return 0;
104+
return 0;
116105
}

0 commit comments

Comments
 (0)