X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/a88a4036e14334a7a01fc40a7d547687ba6dee38..458ff11:/include/simgrid/s4u/conditionVariable.hpp diff --git a/include/simgrid/s4u/conditionVariable.hpp b/include/simgrid/s4u/conditionVariable.hpp index 9c9c58ac65..cad750720d 100644 --- a/include/simgrid/s4u/conditionVariable.hpp +++ b/include/simgrid/s4u/conditionVariable.hpp @@ -6,9 +6,15 @@ #ifndef SIMGRID_S4U_COND_VARIABLE_HPP #define SIMGRID_S4U_COND_VARIABLE_HPP +#include +#include #include #include // std::swap +#include + +#include + #include #include @@ -17,52 +23,67 @@ namespace s4u { class Mutex; +/** A condition variable + * + * This is based on std::condition_variable and should respect the same + * semantic. But we currently use (only) double for both durations and + * timestamp timeouts. + */ XBT_PUBLIC_CLASS ConditionVariable { - +private: + friend s_smx_cond; + smx_cond_t cond_; + ConditionVariable(smx_cond_t cond) : cond_(cond) {} public: - ConditionVariable(); - ConditionVariable(ConditionVariable* cond) : cond_(SIMIX_cond_ref(cond->cond_)) {} - ~ConditionVariable(); + ConditionVariable(ConditionVariable const&) = delete; + ConditionVariable& operator=(ConditionVariable const&) = delete; + + friend XBT_PUBLIC(void) intrusive_ptr_add_ref(ConditionVariable* cond); + friend XBT_PUBLIC(void) intrusive_ptr_release(ConditionVariable* cond); + using Ptr = boost::intrusive_ptr; + + static Ptr createConditionVariable(); + + // Wait functions: + + void wait(std::unique_lock& lock); + std::cv_status wait_until(std::unique_lock& lock, double timeout_time); + std::cv_status wait_for(std::unique_lock& lock, double duration); + + // Variants which takes a predicate: - // Copy+move (with the copy-and-swap idiom): - ConditionVariable(ConditionVariable const& cond) : cond_(SIMIX_cond_ref(cond.cond_)) {} - friend void swap(ConditionVariable& first, ConditionVariable& second) + template + void wait(std::unique_lock& lock, P pred) { - using std::swap; - swap(first.cond_, second.cond_); + while (!pred()) + wait(lock); } - ConditionVariable& operator=(ConditionVariable cond) + template + bool wait_until(std::unique_lock& lock, double timeout_time, P pred) { - swap(*this, cond); - return *this; + while (!pred()) + if (this->wait_until(lock, timeout_time) == std::cv_status::timeout) + return pred(); + return true; } - ConditionVariable(ConditionVariable&& cond) : cond_(nullptr) + template + bool wait_for(std::unique_lock& lock, double duration, P pred) { - swap(*this, cond); + return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred)); } - bool valid() const - { - return cond_ != nullptr; - } - - /** - * Wait functions - */ - void wait(std::unique_lock& lock); - void wait_for(std::unique_lock& lock, double time); + // Notify functions - /** - * Notify functions - */ - void notify(); + void notify_one(); void notify_all(); -private: - smx_cond_t cond_; - + XBT_ATTRIB_DEPRECATED("Use notify_one() instead") + void notify() { notify_one(); } }; + +using ConditionVariablePtr = ConditionVariable::Ptr; + }} // namespace simgrid::s4u #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */