1227825Stheraven//===-------------------- condition_variable.cpp --------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10227825Stheraven#include "condition_variable" 11227825Stheraven#include "thread" 12227825Stheraven#include "system_error" 13227825Stheraven#include "cassert" 14227825Stheraven 15227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 16227825Stheraven 17227825Stheravencondition_variable::~condition_variable() 18227825Stheraven{ 19232950Stheraven pthread_cond_destroy(&__cv_); 20227825Stheraven} 21227825Stheraven 22227825Stheravenvoid 23243376Sdimcondition_variable::notify_one() _NOEXCEPT 24227825Stheraven{ 25227825Stheraven pthread_cond_signal(&__cv_); 26227825Stheraven} 27227825Stheraven 28227825Stheravenvoid 29243376Sdimcondition_variable::notify_all() _NOEXCEPT 30227825Stheraven{ 31227825Stheraven pthread_cond_broadcast(&__cv_); 32227825Stheraven} 33227825Stheraven 34227825Stheravenvoid 35227825Stheravencondition_variable::wait(unique_lock<mutex>& lk) 36227825Stheraven{ 37227825Stheraven if (!lk.owns_lock()) 38227825Stheraven __throw_system_error(EPERM, 39227825Stheraven "condition_variable::wait: mutex not locked"); 40227825Stheraven int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); 41227825Stheraven if (ec) 42227825Stheraven __throw_system_error(ec, "condition_variable wait failed"); 43227825Stheraven} 44227825Stheraven 45227825Stheravenvoid 46227825Stheravencondition_variable::__do_timed_wait(unique_lock<mutex>& lk, 47227825Stheraven chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) 48227825Stheraven{ 49227825Stheraven using namespace chrono; 50227825Stheraven if (!lk.owns_lock()) 51227825Stheraven __throw_system_error(EPERM, 52227825Stheraven "condition_variable::timed wait: mutex not locked"); 53227825Stheraven nanoseconds d = tp.time_since_epoch(); 54243376Sdim if (d > nanoseconds(0x59682F000000E941)) 55243376Sdim d = nanoseconds(0x59682F000000E941); 56227825Stheraven timespec ts; 57227825Stheraven seconds s = duration_cast<seconds>(d); 58243376Sdim typedef decltype(ts.tv_sec) ts_sec; 59243376Sdim _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); 60243376Sdim if (s.count() < ts_sec_max) 61243376Sdim { 62243376Sdim ts.tv_sec = static_cast<ts_sec>(s.count()); 63243376Sdim ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); 64243376Sdim } 65243376Sdim else 66243376Sdim { 67243376Sdim ts.tv_sec = ts_sec_max; 68243376Sdim ts.tv_nsec = giga::num - 1; 69243376Sdim } 70227825Stheraven int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); 71227825Stheraven if (ec != 0 && ec != ETIMEDOUT) 72227825Stheraven __throw_system_error(ec, "condition_variable timed_wait failed"); 73227825Stheraven} 74227825Stheraven 75227825Stheravenvoid 76227825Stheravennotify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) 77227825Stheraven{ 78227825Stheraven __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release()); 79227825Stheraven} 80227825Stheraven 81227825Stheraven_LIBCPP_END_NAMESPACE_STD 82