• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //===-------------------- condition_variable.cpp --------------------------===//
2  //
3  //                     The LLVM Compiler Infrastructure
4  //
5  // This file is dual licensed under the MIT and the University of Illinois Open
6  // Source Licenses. See LICENSE.TXT for details.
7  //
8  //===----------------------------------------------------------------------===//
9  
10  #include "condition_variable"
11  #include "thread"
12  #include "system_error"
13  #include "cassert"
14  
15  #if !_LIBCPP_SINGLE_THREADED
16  
17  _LIBCPP_BEGIN_NAMESPACE_STD
18  
~condition_variable()19  condition_variable::~condition_variable()
20  {
21      pthread_cond_destroy(&__cv_);
22  }
23  
24  void
notify_one()25  condition_variable::notify_one() _NOEXCEPT
26  {
27      pthread_cond_signal(&__cv_);
28  }
29  
30  void
notify_all()31  condition_variable::notify_all() _NOEXCEPT
32  {
33      pthread_cond_broadcast(&__cv_);
34  }
35  
36  void
wait(unique_lock<mutex> & lk)37  condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT
38  {
39      if (!lk.owns_lock())
40          __throw_system_error(EPERM,
41                                    "condition_variable::wait: mutex not locked");
42      int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle());
43      if (ec)
44          __throw_system_error(ec, "condition_variable wait failed");
45  }
46  
47  void
__do_timed_wait(unique_lock<mutex> & lk,chrono::time_point<chrono::system_clock,chrono::nanoseconds> tp)48  condition_variable::__do_timed_wait(unique_lock<mutex>& lk,
49       chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT
50  {
51      using namespace chrono;
52      if (!lk.owns_lock())
53          __throw_system_error(EPERM,
54                              "condition_variable::timed wait: mutex not locked");
55      nanoseconds d = tp.time_since_epoch();
56      if (d > nanoseconds(0x59682F000000E941))
57          d = nanoseconds(0x59682F000000E941);
58      timespec ts;
59      seconds s = duration_cast<seconds>(d);
60      typedef decltype(ts.tv_sec) ts_sec;
61      _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();
62      if (s.count() < ts_sec_max)
63      {
64          ts.tv_sec = static_cast<ts_sec>(s.count());
65          ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count());
66      }
67      else
68      {
69          ts.tv_sec = ts_sec_max;
70          ts.tv_nsec = giga::num - 1;
71      }
72      int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);
73      if (ec != 0 && ec != ETIMEDOUT)
74          __throw_system_error(ec, "condition_variable timed_wait failed");
75  }
76  
77  void
notify_all_at_thread_exit(condition_variable & cond,unique_lock<mutex> lk)78  notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
79  {
80      __thread_local_data()->notify_all_at_thread_exit(&cond, lk.release());
81  }
82  
83  _LIBCPP_END_NAMESPACE_STD
84  
85  #endif // !_LIBCPP_SINGLE_THREADED
86  
87