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 10278724Sdim#include "__config" 11278724Sdim 12278724Sdim#ifndef _LIBCPP_HAS_NO_THREADS 13278724Sdim 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{ 23232950Stheraven pthread_cond_destroy(&__cv_); 24227825Stheraven} 25227825Stheraven 26227825Stheravenvoid 27241903Sdimcondition_variable::notify_one() _NOEXCEPT 28227825Stheraven{ 29227825Stheraven pthread_cond_signal(&__cv_); 30227825Stheraven} 31227825Stheraven 32227825Stheravenvoid 33241903Sdimcondition_variable::notify_all() _NOEXCEPT 34227825Stheraven{ 35227825Stheraven pthread_cond_broadcast(&__cv_); 36227825Stheraven} 37227825Stheraven 38227825Stheravenvoid 39278724Sdimcondition_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, 51278724Sdim 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(); 58241903Sdim if (d > nanoseconds(0x59682F000000E941)) 59241903Sdim d = nanoseconds(0x59682F000000E941); 60227825Stheraven timespec ts; 61227825Stheraven seconds s = duration_cast<seconds>(d); 62241903Sdim typedef decltype(ts.tv_sec) ts_sec; 63241903Sdim _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); 64241903Sdim if (s.count() < ts_sec_max) 65241903Sdim { 66241903Sdim ts.tv_sec = static_cast<ts_sec>(s.count()); 67241903Sdim ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); 68241903Sdim } 69241903Sdim else 70241903Sdim { 71241903Sdim ts.tv_sec = ts_sec_max; 72241903Sdim ts.tv_nsec = giga::num - 1; 73241903Sdim } 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 86278724Sdim 87278724Sdim#endif // !_LIBCPP_HAS_NO_THREADS 88