OLD | NEW |
(Empty) | |
| 1 //===-------------------- condition_variable.cpp --------------------------===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is dual licensed under the MIT and the University of Illinois Open |
| 6 // Source Licenses. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 |
| 10 #include "condition_variable" |
| 11 #include "thread" |
| 12 #include "system_error" |
| 13 #include "cassert" |
| 14 |
| 15 _LIBCPP_BEGIN_NAMESPACE_STD |
| 16 |
| 17 condition_variable::~condition_variable() |
| 18 { |
| 19 pthread_cond_destroy(&__cv_); |
| 20 } |
| 21 |
| 22 void |
| 23 condition_variable::notify_one() _NOEXCEPT |
| 24 { |
| 25 pthread_cond_signal(&__cv_); |
| 26 } |
| 27 |
| 28 void |
| 29 condition_variable::notify_all() _NOEXCEPT |
| 30 { |
| 31 pthread_cond_broadcast(&__cv_); |
| 32 } |
| 33 |
| 34 void |
| 35 condition_variable::wait(unique_lock<mutex>& lk) |
| 36 { |
| 37 if (!lk.owns_lock()) |
| 38 __throw_system_error(EPERM, |
| 39 "condition_variable::wait: mutex not locked"); |
| 40 int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); |
| 41 if (ec) |
| 42 __throw_system_error(ec, "condition_variable wait failed"); |
| 43 } |
| 44 |
| 45 void |
| 46 condition_variable::__do_timed_wait(unique_lock<mutex>& lk, |
| 47 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) |
| 48 { |
| 49 using namespace chrono; |
| 50 if (!lk.owns_lock()) |
| 51 __throw_system_error(EPERM, |
| 52 "condition_variable::timed wait: mutex not locked"); |
| 53 nanoseconds d = tp.time_since_epoch(); |
| 54 if (d > nanoseconds(0x59682F000000E941)) |
| 55 d = nanoseconds(0x59682F000000E941); |
| 56 timespec ts; |
| 57 seconds s = duration_cast<seconds>(d); |
| 58 typedef decltype(ts.tv_sec) ts_sec; |
| 59 _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); |
| 60 if (s.count() < ts_sec_max) |
| 61 { |
| 62 ts.tv_sec = static_cast<ts_sec>(s.count()); |
| 63 ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); |
| 64 } |
| 65 else |
| 66 { |
| 67 ts.tv_sec = ts_sec_max; |
| 68 ts.tv_nsec = giga::num - 1; |
| 69 } |
| 70 int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); |
| 71 if (ec != 0 && ec != ETIMEDOUT) |
| 72 __throw_system_error(ec, "condition_variable timed_wait failed"); |
| 73 } |
| 74 |
| 75 void |
| 76 notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) |
| 77 { |
| 78 __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release()); |
| 79 } |
| 80 |
| 81 _LIBCPP_END_NAMESPACE_STD |
OLD | NEW |