From: Gabriel Corona Date: Tue, 21 Jun 2016 09:30:24 +0000 (+0200) Subject: [s4u] ConditionVariable, implement missing wait methods X-Git-Tag: v3_14~907 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/c111bd7eb06c7bd66de5a930ebf86f69c7f984df?hp=cc14b4de408850d5efb523c8da5b26d0fcfd0a1f [s4u] ConditionVariable, implement missing wait methods --- diff --git a/include/simgrid/s4u/conditionVariable.hpp b/include/simgrid/s4u/conditionVariable.hpp index 252a4f153f..2858244ef6 100644 --- a/include/simgrid/s4u/conditionVariable.hpp +++ b/include/simgrid/s4u/conditionVariable.hpp @@ -48,28 +48,36 @@ public: return cond_ != nullptr; } - /** - * Wait functions - */ + // Wait functions: + void wait(std::unique_lock& lock); - // TODO, return std::cv_status + std::cv_status wait_until(std::unique_lock& lock, double timeout_time); std::cv_status wait_for(std::unique_lock& lock, double duration); - // TODO, wait_until - /** Variant which takes a predice */ + // Variants which takes a predicate: + template void wait(std::unique_lock& lock, P pred) { while (!pred()) wait(lock); } + 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)); + } - // TODO, return std::cv_status - // TODO,wait_until + // Notify functions - /** - * Notify functions - */ void notify(); void notify_all(); diff --git a/src/s4u/s4u_conditionVariable.cpp b/src/s4u/s4u_conditionVariable.cpp index bb367af7e0..28c9fc0c7f 100644 --- a/src/s4u/s4u_conditionVariable.cpp +++ b/src/s4u/s4u_conditionVariable.cpp @@ -22,29 +22,43 @@ s4u::ConditionVariable::~ConditionVariable() { void s4u::ConditionVariable::wait(std::unique_lock& lock) { simcall_cond_wait(cond_, lock.mutex()->mutex_); } - + std::cv_status s4u::ConditionVariable::wait_for(std::unique_lock& lock, double timeout) { try { simcall_cond_wait_timeout(cond_, lock.mutex()->mutex_, timeout); return std::cv_status::timeout; } catch (xbt_ex& e) { + + // If the exception was a timeout, we have to take the lock again: if (e.category == timeout_error) { - // We have to take the lock: try { lock.mutex()->lock(); + return std::cv_status::timeout; } catch (...) { std::terminate(); } - return std::cv_status::timeout; } + + // Another exception: should we reaquire the lock? std::terminate(); } catch (...) { std::terminate(); } } + +std::cv_status s4u::ConditionVariable::wait_until(std::unique_lock& lock, double timeout_time) +{ + double now = SIMIX_get_clock(); + double timeout; + if (timeout_time < now) + timeout = 0.0; + else + timeout = timeout_time - now; + return this->wait_for(lock, timeout); +} /** * Notify functions