X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/6699370d7de47422c60b0a6c2f2d30dad680dfca..1961b7e6a40a8070be7d95fe180fd65a29af0ed7:/include/simgrid/s4u/conditionVariable.hpp diff --git a/include/simgrid/s4u/conditionVariable.hpp b/include/simgrid/s4u/conditionVariable.hpp index 05304064cc..973b982469 100644 --- a/include/simgrid/s4u/conditionVariable.hpp +++ b/include/simgrid/s4u/conditionVariable.hpp @@ -6,6 +6,7 @@ #ifndef SIMGRID_S4U_COND_VARIABLE_HPP #define SIMGRID_S4U_COND_VARIABLE_HPP +#include #include #include #include @@ -16,63 +17,51 @@ #include #include -#include +#include +#include namespace simgrid { namespace s4u { class Mutex; -/** A condition variable +/** @brief A condition variable + * @ingroup s4u_api * - * This is based on std::condition_variable and should respect the same + * This is a drop-in replacement of `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; - // 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) - { - using std::swap; - swap(first.cond_, second.cond_); - } - ConditionVariable& operator=(ConditionVariable cond) - { - swap(*this, cond); - return *this; - } - ConditionVariable(ConditionVariable&& cond) : cond_(nullptr) - { - swap(*this, cond); - } + friend XBT_PUBLIC(void) intrusive_ptr_add_ref(ConditionVariable* cond); + friend XBT_PUBLIC(void) intrusive_ptr_release(ConditionVariable* cond); + using Ptr = boost::intrusive_ptr; - bool valid() const - { - return cond_ != nullptr; - } - - // 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); + static Ptr createConditionVariable(); - // Variants which takes a predicate: + // Wait functions without time: + void wait(std::unique_lock& lock); template void wait(std::unique_lock& lock, P pred) { while (!pred()) wait(lock); } + + // Wait function taking a plain double as time: + + std::cv_status wait_until(std::unique_lock& lock, double timeout_time); + std::cv_status wait_for(std::unique_lock& lock, double duration); template bool wait_until(std::unique_lock& lock, double timeout_time, P pred) { @@ -87,6 +76,39 @@ public: return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred)); } + // Wait function taking a C++ style time: + + template + bool wait_for( + std::unique_lock& lock, std::chrono::duration duration, + P pred) + { + auto seconds = std::chrono::duration_cast(duration); + return this->wait_for(lock, seconds.count(), pred); + } + template + std::cv_status wait_for( + std::unique_lock& lock, std::chrono::duration duration) + { + auto seconds = std::chrono::duration_cast(duration); + return this->wait_for(lock, seconds.count()); + } + template + std::cv_status wait_until(std::unique_lock& lock, + const SimulationTimePoint& timeout_time) + { + auto timeout_native = std::chrono::time_point_cast(timeout_time); + return this->wait_until(lock, timeout_native.time_since_epoch().count()); + } + template + bool wait_until(std::unique_lock& lock, + const SimulationTimePoint& timeout_time, P pred) + { + auto timeout_native = std::chrono::time_point_cast(timeout_time); + return this->wait_until(lock, timeout_native.time_since_epoch().count(), + std::move(pred)); + } + // Notify functions void notify_one(); @@ -94,11 +116,10 @@ public: XBT_ATTRIB_DEPRECATED("Use notify_one() instead") void notify() { notify_one(); } +}; -private: - smx_cond_t cond_; +using ConditionVariablePtr = ConditionVariable::Ptr; -}; }} // namespace simgrid::s4u #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */