Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
cad750720d2348850ef8e127bd1171fe66b7db0a
[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 private:
34   friend s_smx_cond;
35   smx_cond_t cond_;
36   ConditionVariable(smx_cond_t cond) : cond_(cond) {}
37 public:
38
39   ConditionVariable(ConditionVariable const&) = delete;
40   ConditionVariable& operator=(ConditionVariable const&) = delete;
41
42   friend XBT_PUBLIC(void) intrusive_ptr_add_ref(ConditionVariable* cond);
43   friend XBT_PUBLIC(void) intrusive_ptr_release(ConditionVariable* cond);
44   using Ptr = boost::intrusive_ptr<ConditionVariable>;
45
46   static Ptr createConditionVariable();
47
48   //  Wait functions:
49
50   void wait(std::unique_lock<Mutex>& lock);
51   std::cv_status wait_until(std::unique_lock<Mutex>& lock, double timeout_time);
52   std::cv_status wait_for(std::unique_lock<Mutex>& lock, double duration);
53
54   // Variants which takes a predicate:
55
56   template<class P>
57   void wait(std::unique_lock<Mutex>& lock, P pred)
58   {
59     while (!pred())
60       wait(lock);
61   }
62   template<class P>
63   bool wait_until(std::unique_lock<Mutex>& lock, double timeout_time, P pred)
64   {
65     while (!pred())
66       if (this->wait_until(lock, timeout_time) == std::cv_status::timeout)
67         return pred();
68     return true;
69   }
70   template<class P>
71   bool wait_for(std::unique_lock<Mutex>& lock, double duration, P pred)
72   {
73     return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred));
74   }
75
76   // Notify functions
77
78   void notify_one();
79   void notify_all();
80
81   XBT_ATTRIB_DEPRECATED("Use notify_one() instead")
82   void notify() { notify_one(); }
83 };
84
85 using ConditionVariablePtr = ConditionVariable::Ptr;
86
87 }} // namespace simgrid::s4u
88
89 #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */