Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] Allocate Mutex on the heap and return MutexPtr
[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 <future>
11 #include <mutex>
12 #include <utility> // std::swap
13
14 #include <boost/intrusive_ptr.hpp>
15
16 #include <xbt/base.h>
17
18 #include <simgrid/simix.h>
19 #include <simgrid/s4u/mutex.hpp>
20
21 namespace simgrid {
22 namespace s4u {
23
24 class Mutex;
25
26 /** A condition variable
27  *
28  *  This is based on std::condition_variable and should respect the same
29  *  semantic. But we currently use (only) double for both durations and
30  *  timestamp timeouts.
31  */
32 XBT_PUBLIC_CLASS ConditionVariable {
33   
34 public:
35   ConditionVariable();
36
37   ConditionVariable(ConditionVariable* cond) : cond_(SIMIX_cond_ref(cond->cond_)) {}
38   ~ConditionVariable();
39
40   // Copy+move (with the copy-and-swap idiom):
41   ConditionVariable(ConditionVariable const& cond) : cond_(SIMIX_cond_ref(cond.cond_)) {}
42   friend void swap(ConditionVariable& first, ConditionVariable& second)
43   {
44     using std::swap;
45     swap(first.cond_, second.cond_);
46   }
47   ConditionVariable& operator=(ConditionVariable cond)
48   {
49     swap(*this, cond);
50     return *this;
51   }
52   ConditionVariable(ConditionVariable&& cond) : cond_(nullptr)
53   {
54     swap(*this, cond);
55   }
56
57   bool valid() const
58   {
59     return cond_ != nullptr;
60   }
61   
62   //  Wait functions:
63
64   void wait(std::unique_lock<Mutex>& lock);
65   std::cv_status wait_until(std::unique_lock<Mutex>& lock, double timeout_time);
66   std::cv_status wait_for(std::unique_lock<Mutex>& lock, double duration);
67
68   // Variants which takes a predicate:
69
70   template<class P>
71   void wait(std::unique_lock<Mutex>& lock, P pred)
72   {
73     while (!pred())
74       wait(lock);
75   }
76   template<class P>
77   bool wait_until(std::unique_lock<Mutex>& lock, double timeout_time, P pred)
78   {
79     while (!pred())
80       if (this->wait_until(lock, timeout_time) == std::cv_status::timeout)
81         return pred();
82     return true;
83   }
84   template<class P>
85   bool wait_for(std::unique_lock<Mutex>& lock, double duration, P pred)
86   {
87     return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred));
88   }
89
90   // Notify functions
91
92   void notify_one();
93   void notify_all();
94
95   XBT_ATTRIB_DEPRECATED("Use notify_one() instead")
96   void notify() { notify_one(); }
97
98 private:
99   smx_cond_t cond_;
100
101 };
102 }} // namespace simgrid::s4u
103
104 #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */