15
15
#include < system_error>
16
16
#include < __threading_support>
17
17
18
- #include < time.h>
19
18
20
19
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21
20
#pragma GCC system_header
@@ -338,75 +337,23 @@ public:
338
337
private:
339
338
void __do_timed_wait (unique_lock<mutex>& __lk,
340
339
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;
348
340
};
349
341
#endif // !_LIBCPP_HAS_NO_THREADS
350
342
351
- template <class _Rep , class _Period >
343
+ template <class _To , class _Rep , class _Period >
352
344
inline _LIBCPP_INLINE_VISIBILITY
353
345
typename enable_if
354
346
<
355
- is_floating_point<_Rep >::value,
356
- chrono::nanoseconds
347
+ chrono::__is_duration<_To >::value,
348
+ _To
357
349
>::type
358
- __safe_nanosecond_cast (chrono::duration<_Rep, _Period> __d)
350
+ __ceil (chrono::duration<_Rep, _Period> __d)
359
351
{
360
352
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;
410
357
}
411
358
412
359
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -424,15 +371,7 @@ condition_variable::wait_until(unique_lock<mutex>& __lk,
424
371
const chrono::time_point<_Clock, _Duration>& __t )
425
372
{
426
373
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 ());
436
375
return _Clock::now () < __t ? cv_status::no_timeout : cv_status::timeout;
437
376
}
438
377
@@ -458,25 +397,15 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
458
397
using namespace chrono ;
459
398
if (__d <= __d.zero ())
460
399
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 ();
462
403
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 ());
480
409
return steady_clock::now () - __c_now < __d ? cv_status::no_timeout :
481
410
cv_status::timeout;
482
411
}
@@ -492,46 +421,6 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
492
421
_VSTD::move (__pred));
493
422
}
494
423
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
-
535
424
#endif // !_LIBCPP_HAS_NO_THREADS
536
425
537
426
_LIBCPP_END_NAMESPACE_STD
0 commit comments