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 10276792Sdim#include "__config" 11276792Sdim 12276792Sdim#ifndef _LIBCPP_HAS_NO_THREADS 13276792Sdim 14227825Stheraven#include "condition_variable" 15227825Stheraven#include "thread" 16227825Stheraven#include "system_error" 17227825Stheraven#include "cassert" 18227825Stheraven 19227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 20227825Stheraven 21227825Stheravencondition_variable::~condition_variable() 22227825Stheraven{ 23232924Stheraven pthread_cond_destroy(&__cv_); 24227825Stheraven} 25227825Stheraven 26227825Stheravenvoid 27241900Sdimcondition_variable::notify_one() _NOEXCEPT 28227825Stheraven{ 29227825Stheraven pthread_cond_signal(&__cv_); 30227825Stheraven} 31227825Stheraven 32227825Stheravenvoid 33241900Sdimcondition_variable::notify_all() _NOEXCEPT 34227825Stheraven{ 35227825Stheraven pthread_cond_broadcast(&__cv_); 36227825Stheraven} 37227825Stheraven 38227825Stheravenvoid 39276792Sdimcondition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT 40227825Stheraven{ 41227825Stheraven if (!lk.owns_lock()) 42227825Stheraven __throw_system_error(EPERM, 43227825Stheraven "condition_variable::wait: mutex not locked"); 44227825Stheraven int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); 45227825Stheraven if (ec) 46227825Stheraven __throw_system_error(ec, "condition_variable wait failed"); 47227825Stheraven} 48227825Stheraven 49227825Stheravenvoid 50227825Stheravencondition_variable::__do_timed_wait(unique_lock<mutex>& lk, 51276792Sdim chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT 52227825Stheraven{ 53227825Stheraven using namespace chrono; 54227825Stheraven if (!lk.owns_lock()) 55227825Stheraven __throw_system_error(EPERM, 56227825Stheraven "condition_variable::timed wait: mutex not locked"); 57227825Stheraven nanoseconds d = tp.time_since_epoch(); 58241900Sdim if (d > nanoseconds(0x59682F000000E941)) 59241900Sdim d = nanoseconds(0x59682F000000E941); 60227825Stheraven timespec ts; 61227825Stheraven seconds s = duration_cast<seconds>(d); 62241900Sdim typedef decltype(ts.tv_sec) ts_sec; 63241900Sdim _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); 64241900Sdim if (s.count() < ts_sec_max) 65241900Sdim { 66241900Sdim ts.tv_sec = static_cast<ts_sec>(s.count()); 67241900Sdim ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); 68241900Sdim } 69241900Sdim else 70241900Sdim { 71241900Sdim ts.tv_sec = ts_sec_max; 72241900Sdim ts.tv_nsec = giga::num - 1; 73241900Sdim } 74227825Stheraven int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); 75227825Stheraven if (ec != 0 && ec != ETIMEDOUT) 76227825Stheraven __throw_system_error(ec, "condition_variable timed_wait failed"); 77227825Stheraven} 78227825Stheraven 79227825Stheravenvoid 80227825Stheravennotify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) 81227825Stheraven{ 82227825Stheraven __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release()); 83227825Stheraven} 84227825Stheraven 85227825Stheraven_LIBCPP_END_NAMESPACE_STD 86276792Sdim 87276792Sdim#endif // !_LIBCPP_HAS_NO_THREADS 88