X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/43388fb03f79aae5ddd0572c0081cfbe1cf22670..ec02e7dbba648af74ef31ac28929d153db6d53f5:/include/simgrid/s4u/ConditionVariable.hpp diff --git a/include/simgrid/s4u/ConditionVariable.hpp b/include/simgrid/s4u/ConditionVariable.hpp index 2ccf89d5e9..448b4a8391 100644 --- a/include/simgrid/s4u/ConditionVariable.hpp +++ b/include/simgrid/s4u/ConditionVariable.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2017. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,110 +6,89 @@ #ifndef SIMGRID_S4U_COND_VARIABLE_HPP #define SIMGRID_S4U_COND_VARIABLE_HPP -#include -#include -#include -#include -#include // std::swap - -#include - -#include +#include #include +#include #include -#include -namespace simgrid { -namespace s4u { +#include -/** @brief A condition variable - * @ingroup s4u_api - * - * 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. +namespace simgrid::s4u { + +/** + * @beginrst + * SimGrid's condition variables are meant to be drop-in replacements of ``std::condition_variable``. + * Please refer to the `documentation of standard C++ `_ + * for more information on condition variables. A SimGrid example is available in Section :ref:`s4u_ex_IPC`. + * @endrst */ -XBT_PUBLIC_CLASS ConditionVariable -{ +class XBT_PUBLIC ConditionVariable { private: - friend s_smx_cond; - smx_cond_t cond_; - ConditionVariable(smx_cond_t cond) : cond_(cond) {} -public: - ConditionVariable(ConditionVariable const&) = delete; - ConditionVariable& operator=(ConditionVariable const&) = delete; +#ifndef DOXYGEN + friend kernel::activity::ConditionVariableImpl; + friend XBT_PUBLIC void kernel::activity::intrusive_ptr_release(kernel::activity::ConditionVariableImpl* cond); +#endif - friend XBT_PUBLIC(void) intrusive_ptr_add_ref(ConditionVariable * cond); - friend XBT_PUBLIC(void) intrusive_ptr_release(ConditionVariable * cond); - using Ptr = boost::intrusive_ptr; + kernel::activity::ConditionVariableImpl* const pimpl_; - static Ptr createConditionVariable(); + explicit ConditionVariable(kernel::activity::ConditionVariableImpl* cond) : pimpl_(cond) {} + ~ConditionVariable() = default; +#ifndef DOXYGEN + ConditionVariable(ConditionVariable const&) = delete; + ConditionVariable& operator=(ConditionVariable const&) = delete; - // Wait functions without time: + friend XBT_PUBLIC void intrusive_ptr_add_ref(const ConditionVariable* cond); + friend XBT_PUBLIC void intrusive_ptr_release(const ConditionVariable* cond); +#endif - void wait(MutexPtr lock); - void wait(std::unique_lock & lock); - template void wait(std::unique_lock & lock, P pred) +public: + /** \static Create a new condition variable and return a smart pointer + * + * @beginrst + * You should only manipulate :cpp:type:`simgrid::s4u::ConditionVariablePtr`, as created by this function (see also :ref:`s4u_raii`). + * @endrst + */ + static ConditionVariablePtr create(); + + /// Wait until notification, with no timeout + void wait(s4u::MutexPtr lock); + /// Wait until notification, with no timeout + void wait(const std::unique_lock& lock); + template void wait(const std::unique_lock& lock, P pred) { - while (!pred()) + while (not 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) - { - while (!pred()) - if (this->wait_until(lock, timeout_time) == std::cv_status::timeout) - return pred(); - return true; - } - template bool wait_for(std::unique_lock & lock, double duration, P pred) - { - return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred)); - } + /// Wait until the given instant (specified as a plain double) + std::cv_status wait_until(const std::unique_lock& lock, double timeout_time); + /// Wait for the given amount of seconds (specified as a plain double) + std::cv_status wait_for(const std::unique_lock& lock, double duration); // 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); - } + /// Wait for the given amount of seconds (specified in C++ style) template - std::cv_status wait_for(std::unique_lock & lock, std::chrono::duration duration) + std::cv_status wait_for(const std::unique_lock& lock, std::chrono::duration duration) { auto seconds = std::chrono::duration_cast(duration); return this->wait_for(lock, seconds.count()); } + /** Wait until the given instant (specified in C++ style) */ template - std::cv_status wait_until(std::unique_lock & lock, const SimulationTimePoint& timeout_time) + std::cv_status wait_until(const 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 + /** Unblock one actor blocked on that condition variable. If none was blocked, nothing happens. */ void notify_one(); + /** Unblock all actors blocked on that condition variable. If none was blocked, nothing happens. */ void notify_all(); - - XBT_ATTRIB_DEPRECATED("Use notify_one() instead") - void notify() { notify_one(); } }; -using ConditionVariablePtr = ConditionVariable::Ptr; -} } // namespace simgrid::s4u #endif