Path: blob/master/libs/c++/src/condition_variable.cpp
12346 views
//===-------------------- condition_variable.cpp --------------------------===//1//2// The LLVM Compiler Infrastructure3//4// This file is dual licensed under the MIT and the University of Illinois Open5// Source Licenses. See LICENSE.TXT for details.6//7//===----------------------------------------------------------------------===//89#include "__config"1011#ifndef _LIBCPP_HAS_NO_THREADS1213#include "condition_variable"14#include "thread"15#include "system_error"16#include "__undef_macros"1718_LIBCPP_BEGIN_NAMESPACE_STD1920condition_variable::~condition_variable()21{22__libcpp_condvar_destroy(&__cv_);23}2425void26condition_variable::notify_one() _NOEXCEPT27{28__libcpp_condvar_signal(&__cv_);29}3031void32condition_variable::notify_all() _NOEXCEPT33{34__libcpp_condvar_broadcast(&__cv_);35}3637void38condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT39{40if (!lk.owns_lock())41__throw_system_error(EPERM,42"condition_variable::wait: mutex not locked");43int ec = __libcpp_condvar_wait(&__cv_, lk.mutex()->native_handle());44if (ec)45__throw_system_error(ec, "condition_variable wait failed");46}4748void49condition_variable::__do_timed_wait(unique_lock<mutex>& lk,50chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT51{52using namespace chrono;53if (!lk.owns_lock())54__throw_system_error(EPERM,55"condition_variable::timed wait: mutex not locked");56nanoseconds d = tp.time_since_epoch();57if (d > nanoseconds(0x59682F000000E941))58d = nanoseconds(0x59682F000000E941);59timespec ts;60seconds s = duration_cast<seconds>(d);61typedef decltype(ts.tv_sec) ts_sec;62_LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();63if (s.count() < ts_sec_max)64{65ts.tv_sec = static_cast<ts_sec>(s.count());66ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count());67}68else69{70ts.tv_sec = ts_sec_max;71ts.tv_nsec = giga::num - 1;72}73int ec = __libcpp_condvar_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);74if (ec != 0 && ec != ETIMEDOUT)75__throw_system_error(ec, "condition_variable timed_wait failed");76}7778void79notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)80{81auto& tl_ptr = __thread_local_data();82// If this thread was not created using std::thread then it will not have83// previously allocated.84if (tl_ptr.get() == nullptr) {85tl_ptr.set_pointer(new __thread_struct);86}87__thread_local_data()->notify_all_at_thread_exit(&cond, lk.release());88}8990_LIBCPP_END_NAMESPACE_STD9192#endif // !_LIBCPP_HAS_NO_THREADS939495