From: Martin Quinson Date: Sun, 15 Apr 2018 21:01:40 +0000 (+0200) Subject: start modernizing ConditionVariableImpl X-Git-Tag: v3.20~424 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/74c54d770c8a3c775a801b64fdaa5b84843798c0 start modernizing ConditionVariableImpl --- diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index f45e35e639..8f0fd64f36 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -61,6 +61,8 @@ namespace activity { XBT_PUBLIC void intrusive_ptr_add_ref(ActivityImpl* activity); XBT_PUBLIC void intrusive_ptr_release(ActivityImpl* activity); + class ConditionVariableImpl; + class CommImpl; using CommImplPtr = boost::intrusive_ptr; class ExecImpl; @@ -133,6 +135,7 @@ typedef simgrid::trace_mgr::trace* tmgr_trace_t; typedef simgrid::kernel::context::Context* smx_context_t; typedef simgrid::kernel::actor::ActorImpl* smx_actor_t; +typedef simgrid::kernel::activity::ConditionVariableImpl* smx_cond_t; typedef simgrid::kernel::activity::MutexImpl* smx_mutex_t; typedef simgrid::kernel::activity::MailboxImpl* smx_mailbox_t; typedef simgrid::surf::StorageImpl* surf_storage_t; @@ -150,6 +153,7 @@ typedef struct kernel_Activity* smx_activity_t; typedef struct s_smx_context* smx_context_t; typedef struct s_smx_actor* smx_actor_t; +typedef struct s_smx_cond_t* smx_cond_t; typedef struct s_smx_mutex* smx_mutex_t; typedef struct s_smx_mailbox* smx_mailbox_t; typedef struct s_surf_storage* surf_storage_t; diff --git a/include/simgrid/s4u/ConditionVariable.hpp b/include/simgrid/s4u/ConditionVariable.hpp index 8e89a59fdd..cf869399d1 100644 --- a/include/simgrid/s4u/ConditionVariable.hpp +++ b/include/simgrid/s4u/ConditionVariable.hpp @@ -23,7 +23,7 @@ namespace s4u { */ class XBT_PUBLIC ConditionVariable { private: - friend s_smx_cond_t; + friend kernel::activity::ConditionVariableImpl; smx_cond_t cond_; explicit ConditionVariable(smx_cond_t cond) : cond_(cond) {} public: diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index 51196db6de..482973ae2a 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -45,10 +45,6 @@ typedef enum { /* ******************************** Synchro ************************************ */ -/** - * \ingroup simix_synchro_management - */ -typedef struct s_smx_cond_t* smx_cond_t; /** * \ingroup simix_synchro_management */ @@ -261,8 +257,6 @@ XBT_PUBLIC int simcall_mutex_trylock(smx_mutex_t mutex); XBT_PUBLIC void simcall_mutex_unlock(smx_mutex_t mutex); XBT_PUBLIC smx_cond_t simcall_cond_init(); -XBT_PUBLIC void SIMIX_cond_unref(smx_cond_t cond); -XBT_PUBLIC smx_cond_t SIMIX_cond_ref(smx_cond_t cond); XBT_PUBLIC void simcall_cond_signal(smx_cond_t cond); XBT_PUBLIC void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex); XBT_PUBLIC void simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double max_duration); diff --git a/include/xbt/synchro.h b/include/xbt/synchro.h index a03505ae73..68d0ee5a6a 100644 --- a/include/xbt/synchro.h +++ b/include/xbt/synchro.h @@ -8,6 +8,7 @@ #ifndef XBT_THREAD_H #define XBT_THREAD_H +#include "simgrid/forward.h" #include #include /* SG_BEGIN_DECL */ @@ -51,7 +52,11 @@ XBT_PUBLIC void xbt_mutex_destroy(xbt_mutex_t mutex); /** @brief Thread condition data type (opaque object) * @hideinitializer */ +#ifdef __cplusplus +typedef simgrid::kernel::activity::ConditionVariableImpl* xbt_cond_t; +#else typedef struct s_smx_cond_* xbt_cond_t; +#endif /** @brief Creates a condition variable */ XBT_PUBLIC xbt_cond_t xbt_cond_init(void); diff --git a/src/kernel/activity/ConditionVariableImpl.cpp b/src/kernel/activity/ConditionVariableImpl.cpp index 349a206e96..b08e892107 100644 --- a/src/kernel/activity/ConditionVariableImpl.cpp +++ b/src/kernel/activity/ConditionVariableImpl.cpp @@ -26,7 +26,7 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout, smx_cond_t SIMIX_cond_init() { XBT_IN("()"); - smx_cond_t cond = new s_smx_cond_t(); + smx_cond_t cond = new simgrid::kernel::activity::ConditionVariableImpl(); XBT_OUT(); return cond; } @@ -79,6 +79,13 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout, XBT_OUT(); } +namespace simgrid { +namespace kernel { +namespace activity { + +ConditionVariableImpl::ConditionVariableImpl() : cond_(this) {} +ConditionVariableImpl::~ConditionVariableImpl() = default; + /** * \brief Signalizes a condition. * @@ -86,16 +93,15 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout, * If there are no process sleeping, no action is done. * \param cond A condition */ -void SIMIX_cond_signal(smx_cond_t cond) +void ConditionVariableImpl::signal() { - XBT_IN("(%p)", cond); - XBT_DEBUG("Signal condition %p", cond); + XBT_DEBUG("Signal condition %p", this); /* If there are processes waiting for the condition choose one and try to make it acquire the mutex */ - if (not cond->sleeping.empty()) { - auto& proc = cond->sleeping.front(); - cond->sleeping.pop_front(); + if (not sleeping.empty()) { + auto& proc = sleeping.front(); + sleeping.pop_front(); /* Destroy waiter's synchronization */ proc.waiting_synchro = nullptr; @@ -119,47 +125,40 @@ void SIMIX_cond_signal(smx_cond_t cond) * * Signal ALL processes waiting on a condition. * If there are no process waiting, no action is done. - * \param cond A condition */ -void SIMIX_cond_broadcast(smx_cond_t cond) +void ConditionVariableImpl::broadcast() { - XBT_IN("(%p)", cond); - XBT_DEBUG("Broadcast condition %p", cond); + XBT_DEBUG("Broadcast condition %p", this); /* Signal the condition until nobody is waiting on it */ - while (not cond->sleeping.empty()) { - SIMIX_cond_signal(cond); - } - XBT_OUT(); + while (not sleeping.empty()) + signal(); } -smx_cond_t SIMIX_cond_ref(smx_cond_t cond) +// boost::intrusive_ptr support: +void intrusive_ptr_add_ref(simgrid::kernel::activity::ConditionVariableImpl* cond) { - if (cond != nullptr) - intrusive_ptr_add_ref(cond); - return cond; + cond->refcount_.fetch_add(1, std::memory_order_relaxed); } -void SIMIX_cond_unref(smx_cond_t cond) +void intrusive_ptr_release(simgrid::kernel::activity::ConditionVariableImpl* cond) { - XBT_IN("(%p)", cond); - XBT_DEBUG("Destroy condition %p", cond); - if (cond != nullptr) { - intrusive_ptr_release(cond); + if (cond->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + xbt_assert(cond->sleeping.empty(), "Cannot destroy conditional since someone is still using it"); + delete cond; } - XBT_OUT(); +} +} // namespace activity +} // namespace kernel } -void intrusive_ptr_add_ref(s_smx_cond_t* cond) +XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond) { - auto previous = cond->refcount_.fetch_add(1); - xbt_assert(previous != 0); + cond->signal(); } -void intrusive_ptr_release(s_smx_cond_t* cond) +XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond) { - if (cond->refcount_.fetch_sub(1) == 1) { - xbt_assert(cond->sleeping.empty(), "Cannot destroy conditional since someone is still using it"); - delete cond; - } + cond->broadcast(); } diff --git a/src/kernel/activity/ConditionVariableImpl.hpp b/src/kernel/activity/ConditionVariableImpl.hpp index e0634e66ae..eeb95d126d 100644 --- a/src/kernel/activity/ConditionVariableImpl.hpp +++ b/src/kernel/activity/ConditionVariableImpl.hpp @@ -10,19 +10,34 @@ #include "src/simix/ActorImpl.hpp" #include -struct s_smx_cond_t { - s_smx_cond_t() : cond_(this) {} +namespace simgrid { +namespace kernel { +namespace activity { + +class XBT_PUBLIC ConditionVariableImpl { +public: + ConditionVariableImpl(); + ~ConditionVariableImpl(); - std::atomic_int_fast32_t refcount_{1}; - smx_mutex_t mutex = nullptr; simgrid::kernel::actor::SynchroList sleeping; /* list of sleeping processes */ + smx_mutex_t mutex = nullptr; simgrid::s4u::ConditionVariable cond_; -}; + void broadcast(); + void signal(); + +private: + std::atomic_int_fast32_t refcount_{1}; + friend void intrusive_ptr_add_ref(ConditionVariableImpl* cond); + friend void intrusive_ptr_release(ConditionVariableImpl* cond); +}; +} // namespace activity +} // namespace kernel +} // namespace simgrid XBT_PRIVATE smx_cond_t SIMIX_cond_init(); -XBT_PRIVATE void SIMIX_cond_broadcast(smx_cond_t cond); -XBT_PRIVATE void SIMIX_cond_signal(smx_cond_t cond); -XBT_PRIVATE void intrusive_ptr_add_ref(s_smx_cond_t* cond); -XBT_PRIVATE void intrusive_ptr_release(s_smx_cond_t* cond); + +// simcall handlers +XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond); +XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond); #endif diff --git a/src/simix/popping_accessors.hpp b/src/simix/popping_accessors.hpp index 3dde9c6da5..5be2202c1b 100644 --- a/src/simix/popping_accessors.hpp +++ b/src/simix/popping_accessors.hpp @@ -1406,8 +1406,10 @@ XBT_PRIVATE void simcall_HANDLER_comm_testany(smx_simcall_t simcall, boost::intr XBT_PRIVATE void simcall_HANDLER_mutex_lock(smx_simcall_t simcall, smx_mutex_t mutex); XBT_PRIVATE int simcall_HANDLER_mutex_trylock(smx_simcall_t simcall, smx_mutex_t mutex); XBT_PRIVATE void simcall_HANDLER_mutex_unlock(smx_simcall_t simcall, smx_mutex_t mutex); +XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond); XBT_PRIVATE void simcall_HANDLER_cond_wait(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex); XBT_PRIVATE void simcall_HANDLER_cond_wait_timeout(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex, double timeout); +XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond); XBT_PRIVATE void simcall_HANDLER_sem_acquire(smx_simcall_t simcall, smx_sem_t sem); XBT_PRIVATE void simcall_HANDLER_sem_acquire_timeout(smx_simcall_t simcall, smx_sem_t sem, double timeout); XBT_PRIVATE void simcall_HANDLER_storage_read(smx_simcall_t simcall, surf_storage_t st, sg_size_t size); diff --git a/src/simix/popping_bodies.cpp b/src/simix/popping_bodies.cpp index f7ce5be20c..9914be1bc2 100644 --- a/src/simix/popping_bodies.cpp +++ b/src/simix/popping_bodies.cpp @@ -203,7 +203,7 @@ inline static smx_cond_t simcall_BODY_cond_init() inline static void simcall_BODY_cond_signal(smx_cond_t cond) { if (0) /* Go to that function to follow the code flow through the simcall barrier */ - SIMIX_cond_signal(cond); + simcall_HANDLER_cond_signal(&SIMIX_process_self()->simcall, cond); return simcall(SIMCALL_COND_SIGNAL, cond); } @@ -224,7 +224,7 @@ inline static void simcall_BODY_cond_wait_timeout(smx_cond_t cond, smx_mutex_t m inline static void simcall_BODY_cond_broadcast(smx_cond_t cond) { if (0) /* Go to that function to follow the code flow through the simcall barrier */ - SIMIX_cond_broadcast(cond); + simcall_HANDLER_cond_broadcast(&SIMIX_process_self()->simcall, cond); return simcall(SIMCALL_COND_BROADCAST, cond); } diff --git a/src/simix/popping_generated.cpp b/src/simix/popping_generated.cpp index bd9f4df373..b9b4caabff 100644 --- a/src/simix/popping_generated.cpp +++ b/src/simix/popping_generated.cpp @@ -187,7 +187,7 @@ case SIMCALL_COND_INIT: break; case SIMCALL_COND_SIGNAL: - SIMIX_cond_signal(simgrid::simix::unmarshal(simcall->args[0])); + simcall_HANDLER_cond_signal(simcall, simgrid::simix::unmarshal(simcall->args[0])); SIMIX_simcall_answer(simcall); break; @@ -200,7 +200,7 @@ case SIMCALL_COND_WAIT_TIMEOUT: break; case SIMCALL_COND_BROADCAST: - SIMIX_cond_broadcast(simgrid::simix::unmarshal(simcall->args[0])); + simcall_HANDLER_cond_broadcast(simcall, simgrid::simix::unmarshal(simcall->args[0])); SIMIX_simcall_answer(simcall); break; diff --git a/src/simix/simcalls.in b/src/simix/simcalls.in index 53330ed8a9..5f695cd0ff 100644 --- a/src/simix/simcalls.in +++ b/src/simix/simcalls.in @@ -63,10 +63,10 @@ int mutex_trylock(smx_mutex_t mutex); void mutex_unlock(smx_mutex_t mutex); smx_cond_t cond_init() [[nohandler]]; -void cond_signal(smx_cond_t cond) [[nohandler]]; +void cond_signal(smx_cond_t cond); void cond_wait(smx_cond_t cond, smx_mutex_t mutex) [[block]]; void cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) [[block]]; -void cond_broadcast(smx_cond_t cond) [[nohandler]]; +void cond_broadcast(smx_cond_t cond); void sem_acquire(smx_sem_t sem) [[block]]; void sem_acquire_timeout(smx_sem_t sem, double timeout) [[block]]; diff --git a/src/xbt/xbt_os_synchro.cpp b/src/xbt/xbt_os_synchro.cpp index ad97cb4374..79b0b19d8e 100644 --- a/src/xbt/xbt_os_synchro.cpp +++ b/src/xbt/xbt_os_synchro.cpp @@ -6,11 +6,11 @@ /* 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. */ +#include "simgrid/simix.h" /* used implementation */ +#include "src/kernel/activity/ConditionVariableImpl.hpp" #include "xbt/ex.hpp" #include "xbt/synchro.h" -#include "simgrid/simix.h" /* used implementation */ - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync, xbt, "Synchronization mechanism"); /****** mutex related functions ******/ @@ -76,5 +76,5 @@ void xbt_cond_broadcast(xbt_cond_t cond) void xbt_cond_destroy(xbt_cond_t cond) { - SIMIX_cond_unref((smx_cond_t)cond); + delete cond; }