From 3a7c50103eca28c3ae0260ae8917c4e37def6c90 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 4 Jul 2016 11:57:44 +0200 Subject: [PATCH] [s4u] Allocate ConditionVariable on the heap and return ConditionVariablePtr --- .../s4u/actions-comm/s4u_actions-comm.cpp | 6 +-- include/simgrid/s4u/conditionVariable.hpp | 41 ++++++------------- src/s4u/s4u_conditionVariable.cpp | 21 +++++++--- src/simix/smx_synchro.cpp | 6 +-- src/simix/smx_synchro_private.h | 12 +++--- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/examples/s4u/actions-comm/s4u_actions-comm.cpp b/examples/s4u/actions-comm/s4u_actions-comm.cpp index 0f6477978b..51c89d3f37 100644 --- a/examples/s4u/actions-comm/s4u_actions-comm.cpp +++ b/examples/s4u/actions-comm/s4u_actions-comm.cpp @@ -164,11 +164,11 @@ static void action_wait(const char *const *action) static void action_barrier(const char *const *action) { static simgrid::s4u::MutexPtr mutex = nullptr; - static simgrid::s4u::ConditionVariable *cond = NULL; + static simgrid::s4u::ConditionVariablePtr cond = nullptr; static int processes_arrived_sofar = 0; if (mutex == nullptr) { // first arriving on the barrier mutex = simgrid::s4u::Mutex::createMutex(); - cond = new simgrid::s4u::ConditionVariable(); + cond = simgrid::s4u::ConditionVariable::createConditionVariable(); processes_arrived_sofar = 0; } ACT_DEBUG("Entering barrier: %s (%d already there)", NAME, processes_arrived_sofar); @@ -188,7 +188,7 @@ static void action_barrier(const char *const *action) processes_arrived_sofar--; if (processes_arrived_sofar<=0) { - delete cond; + cond = nullptr; mutex = nullptr; } } diff --git a/include/simgrid/s4u/conditionVariable.hpp b/include/simgrid/s4u/conditionVariable.hpp index 05304064cc..cad750720d 100644 --- a/include/simgrid/s4u/conditionVariable.hpp +++ b/include/simgrid/s4u/conditionVariable.hpp @@ -30,35 +30,21 @@ class Mutex; * 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; + + static Ptr createConditionVariable(); - bool valid() const - { - return cond_ != nullptr; - } - // Wait functions: void wait(std::unique_lock& lock); @@ -94,11 +80,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 */ diff --git a/src/s4u/s4u_conditionVariable.cpp b/src/s4u/s4u_conditionVariable.cpp index ae293522bb..3200255209 100644 --- a/src/s4u/s4u_conditionVariable.cpp +++ b/src/s4u/s4u_conditionVariable.cpp @@ -4,18 +4,17 @@ #include #include +#include "src/simix/smx_synchro_private.h" #include "simgrid/s4u/conditionVariable.hpp" #include "simgrid/simix.h" namespace simgrid { namespace s4u { -ConditionVariable::ConditionVariable() : cond_(simcall_cond_init()){ - -} - -ConditionVariable::~ConditionVariable() { - SIMIX_cond_unref(cond_); +ConditionVariablePtr ConditionVariable::createConditionVariable() +{ + smx_cond_t cond = simcall_cond_init(); + return ConditionVariablePtr(&cond->cond_, false); } /** @@ -73,5 +72,15 @@ void ConditionVariable::notify_all() { simcall_cond_broadcast(cond_); } +void intrusive_ptr_add_ref(ConditionVariable* cond) +{ + intrusive_ptr_add_ref(cond->cond_); +} + +void intrusive_ptr_release(ConditionVariable* cond) +{ + intrusive_ptr_release(cond->cond_); +} + } } diff --git a/src/simix/smx_synchro.cpp b/src/simix/smx_synchro.cpp index 143e0abde6..b4fd81c0d9 100644 --- a/src/simix/smx_synchro.cpp +++ b/src/simix/smx_synchro.cpp @@ -238,9 +238,8 @@ smx_cond_t SIMIX_cond_init(void) { XBT_IN("()"); simgrid::simix::Process p; - smx_cond_t cond = xbt_new0(s_smx_cond_t, 1); + smx_cond_t cond = new s_smx_cond(); cond->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup)); - cond->mutex = nullptr; cond->refcount_ = 1; XBT_OUT(); return cond; @@ -383,9 +382,8 @@ void intrusive_ptr_release(s_smx_cond_t *cond) if (count == 0) { xbt_assert(xbt_swag_size(cond->sleeping) == 0, "Cannot destroy conditional since someone is still using it"); - xbt_swag_free(cond->sleeping); - xbt_free(cond); + delete cond; } } diff --git a/src/simix/smx_synchro_private.h b/src/simix/smx_synchro_private.h index 338a0b488c..f312483329 100644 --- a/src/simix/smx_synchro_private.h +++ b/src/simix/smx_synchro_private.h @@ -10,6 +10,7 @@ #include #include +#include #include "xbt/base.h" #include "xbt/swag.h" @@ -62,9 +63,12 @@ private: } typedef struct s_smx_cond { - smx_mutex_t mutex; - xbt_swag_t sleeping; /* list of sleeping process */ - std::atomic_int_fast32_t refcount_; + s_smx_cond() : cond_(this) {} + + std::atomic_int_fast32_t refcount_ { 1 }; + smx_mutex_t mutex = nullptr; + xbt_swag_t sleeping = nullptr; /* list of sleeping process */ + simgrid::s4u::ConditionVariable cond_; } s_smx_cond_t; typedef struct s_smx_sem { @@ -72,8 +76,6 @@ typedef struct s_smx_sem { xbt_swag_t sleeping; /* list of sleeping process */ } s_smx_sem_t; - - XBT_PRIVATE void SIMIX_post_synchro(smx_synchro_t synchro); XBT_PRIVATE void SIMIX_synchro_stop_waiting(smx_process_t process, smx_simcall_t simcall); XBT_PRIVATE void SIMIX_synchro_destroy(smx_synchro_t synchro); -- 2.20.1