1142425Snectar//===-------------------- condition_variable.cpp --------------------------===// 2160814Ssimon// 3142425Snectar// The LLVM Compiler Infrastructure 4142425Snectar// 5142425Snectar// This file is dual licensed under the MIT and the University of Illinois Open 6142425Snectar// Source Licenses. See LICENSE.TXT for details. 7142425Snectar// 8142425Snectar//===----------------------------------------------------------------------===// 9142425Snectar 10142425Snectar#include "condition_variable" 11142425Snectar#include "thread" 12142425Snectar#include "system_error" 13142425Snectar#include "cassert" 14142425Snectar 15142425Snectar_LIBCPP_BEGIN_NAMESPACE_STD 16142425Snectar 17142425Snectarcondition_variable::~condition_variable() 18142425Snectar{ 19142425Snectar pthread_cond_destroy(&__cv_); 20142425Snectar} 21238405Sjkim 22142425Snectarvoid 23238405Sjkimcondition_variable::notify_one() _NOEXCEPT 24142425Snectar{ 25142425Snectar pthread_cond_signal(&__cv_); 26142425Snectar} 27142425Snectar 28142425Snectarvoid 29142425Snectarcondition_variable::notify_all() _NOEXCEPT 30142425Snectar{ 31142425Snectar pthread_cond_broadcast(&__cv_); 32142425Snectar} 33142425Snectar 34142425Snectarvoid 35142425Snectarcondition_variable::wait(unique_lock<mutex>& lk) 36142425Snectar{ 37142425Snectar if (!lk.owns_lock()) 38238405Sjkim __throw_system_error(EPERM, 39142425Snectar "condition_variable::wait: mutex not locked"); 40142425Snectar int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); 41142425Snectar if (ec) 42142425Snectar __throw_system_error(ec, "condition_variable wait failed"); 43142425Snectar} 44142425Snectar 45142425Snectarvoid 46142425Snectarcondition_variable::__do_timed_wait(unique_lock<mutex>& lk, 47142425Snectar chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) 48142425Snectar{ 49142425Snectar using namespace chrono; 50142425Snectar if (!lk.owns_lock()) 51160814Ssimon __throw_system_error(EPERM, 52160814Ssimon "condition_variable::timed wait: mutex not locked"); 53142425Snectar nanoseconds d = tp.time_since_epoch(); 54142425Snectar if (d > nanoseconds(0x59682F000000E941)) 55142425Snectar d = nanoseconds(0x59682F000000E941); 56142425Snectar timespec ts; 57142425Snectar seconds s = duration_cast<seconds>(d); 58142425Snectar typedef decltype(ts.tv_sec) ts_sec; 59142425Snectar _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); 60142425Snectar if (s.count() < ts_sec_max) 61142425Snectar { 62142425Snectar ts.tv_sec = static_cast<ts_sec>(s.count()); 63142425Snectar ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); 64142425Snectar } 65142425Snectar else 66284285Sjkim { 67284285Sjkim ts.tv_sec = ts_sec_max; 68142425Snectar ts.tv_nsec = giga::num - 1; 69160814Ssimon } 70142425Snectar int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); 71142425Snectar if (ec != 0 && ec != ETIMEDOUT) 72142425Snectar __throw_system_error(ec, "condition_variable timed_wait failed"); 73142425Snectar} 74142425Snectar 75142425Snectarvoid 76142425Snectarnotify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) 77142425Snectar{ 78142425Snectar __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release()); 79142425Snectar} 80142425Snectar 81238405Sjkim_LIBCPP_END_NAMESPACE_STD 82238405Sjkim