Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
4d59c280be3aa94ce7536a3e57f1b5191ade1847
[simgrid.git] / include / simgrid / s4u / conditionVariable.hpp
1 /* Copyright (c) 2006-2016. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_S4U_COND_VARIABLE_HPP
7 #define SIMGRID_S4U_COND_VARIABLE_HPP
8
9 #include <condition_variable>
10 #include <mutex>
11 #include <utility> // std::swap
12
13 #include <simgrid/simix.h>
14 #include <simgrid/s4u/mutex.hpp>
15
16 namespace simgrid {
17 namespace s4u {
18
19 class Mutex;
20
21 /** A condition variable
22  *
23  *  This is based on std::condition_variable and should respect the same
24  *  semantic. But we currently use (only) double for both durations and
25  *  timestamp timeouts.
26  */
27 XBT_PUBLIC_CLASS ConditionVariable {
28   
29 public:
30   ConditionVariable();
31
32   ConditionVariable(ConditionVariable* cond) : cond_(SIMIX_cond_ref(cond->cond_)) {}
33   ~ConditionVariable();
34
35   // Copy+move (with the copy-and-swap idiom):
36   ConditionVariable(ConditionVariable const& cond) : cond_(SIMIX_cond_ref(cond.cond_)) {}
37   friend void swap(ConditionVariable& first, ConditionVariable& second)
38   {
39     using std::swap;
40     swap(first.cond_, second.cond_);
41   }
42   ConditionVariable& operator=(ConditionVariable cond)
43   {
44     swap(*this, cond);
45     return *this;
46   }
47   ConditionVariable(ConditionVariable&& cond) : cond_(nullptr)
48   {
49     swap(*this, cond);
50   }
51
52   bool valid() const
53   {
54     return cond_ != nullptr;
55   }
56   
57   //  Wait functions:
58
59   void wait(std::unique_lock<Mutex>& lock);
60   std::cv_status wait_until(std::unique_lock<Mutex>& lock, double timeout_time);
61   std::cv_status wait_for(std::unique_lock<Mutex>& lock, double duration);
62
63   // Variants which takes a predicate:
64
65   template<class P>
66   void wait(std::unique_lock<Mutex>& lock, P pred)
67   {
68     while (!pred())
69       wait(lock);
70   }
71   template<class P>
72   bool wait_until(std::unique_lock<Mutex>& lock, double timeout_time, P pred)
73   {
74     while (!pred())
75       if (this->wait_until(lock, timeout_time) == std::cv_status::timeout)
76         return pred();
77     return true;
78   }
79   template<class P>
80   bool wait_for(std::unique_lock<Mutex>& lock, double duration, P pred)
81   {
82     return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred));
83   }
84
85   // Notify functions
86
87   void notify_one();
88   void notify_all();
89
90   XBT_ATTRIB_DEPRECATED("Use notify_one() instead")
91   void notify() { notify_one(); }
92
93 private:
94   smx_cond_t cond_;
95
96 };
97 }} // namespace simgrid::s4u
98
99 #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */