From 5ac4d2b6e654a1bbe13782569e401a875cb9aab6 Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Wed, 13 Feb 2019 10:46:23 +0100 Subject: [PATCH] Objectify Semaphore kernel counterpart --- include/simgrid/forward.h | 10 +++-- include/simgrid/simix.h | 5 --- src/kernel/activity/SemaphoreImpl.cpp | 30 ++++++++++++++ src/kernel/activity/SemaphoreImpl.hpp | 52 +++++++++++++++++++++++++ src/s4u/s4u_Semaphore.cpp | 12 +++--- src/simix/smx_synchro.cpp | 56 +++------------------------ src/simix/smx_synchro_private.hpp | 10 ----- tools/cmake/DefinePackages.cmake | 2 + 8 files changed, 103 insertions(+), 74 deletions(-) create mode 100644 src/kernel/activity/SemaphoreImpl.cpp create mode 100644 src/kernel/activity/SemaphoreImpl.hpp diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index 7f8dc6c625..049fcf96a0 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -113,6 +113,8 @@ namespace activity { typedef boost::intrusive_ptr MutexImplPtr; class RawImpl; typedef boost::intrusive_ptr RawImplPtr; + class SemaphoreImpl; + typedef boost::intrusive_ptr SemaphoreImplPtr; class SleepImpl; typedef boost::intrusive_ptr SleepImplPtr; @@ -185,8 +187,9 @@ typedef boost::intrusive_ptr smx_activi 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::kernel::activity::MutexImpl* smx_mutex_t; +typedef simgrid::kernel::activity::SemaphoreImpl* smx_sem_t; #else @@ -201,11 +204,12 @@ typedef struct s4u_NetZone s4u_NetZone; typedef struct s4u_VM s4u_VM; 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_context* smx_context_t; typedef struct s_smx_mailbox* smx_mailbox_t; +typedef struct s_smx_mutex* smx_mutex_t; +typedef struct s_smx_sem* smx_sem_t; #endif diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index edd9546fd7..4b362d865e 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -46,11 +46,6 @@ typedef enum { } e_smx_state_t; /** @} */ -/* ******************************** Synchro ************************************ */ - -/** @ingroup simix_synchro_management */ -typedef struct s_smx_sem_t* smx_sem_t; - /* ****************************** Process *********************************** */ typedef enum { diff --git a/src/kernel/activity/SemaphoreImpl.cpp b/src/kernel/activity/SemaphoreImpl.cpp new file mode 100644 index 0000000000..8d74f2cb0e --- /dev/null +++ b/src/kernel/activity/SemaphoreImpl.cpp @@ -0,0 +1,30 @@ +/* Copyright (c) 2019. 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. */ + +#include "src/kernel/activity/SemaphoreImpl.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_semaphore, simix_synchro, "Semaphore kernel-space implementation"); + +namespace simgrid { +namespace kernel { +namespace activity { + +void SemaphoreImpl::release() +{ + XBT_DEBUG("Sem release semaphore %p", this); + + if (not sleeping_.empty()) { + auto& actor = sleeping_.front(); + sleeping_.pop_front(); + actor.waiting_synchro = nullptr; + SIMIX_simcall_answer(&actor.simcall); + } else { + value_++; + } +} + +} // namespace activity +} // namespace kernel +} // namespace simgrid diff --git a/src/kernel/activity/SemaphoreImpl.hpp b/src/kernel/activity/SemaphoreImpl.hpp new file mode 100644 index 0000000000..6053af5561 --- /dev/null +++ b/src/kernel/activity/SemaphoreImpl.hpp @@ -0,0 +1,52 @@ +/* Copyright (c) 2019. 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. */ + +#ifndef SIMGRID_KERNEL_ACTIVITY_SEMAPHOREIMPL_HPP_ +#define SIMGRID_KERNEL_ACTIVITY_SEMAPHOREIMPL_HPP_ + +#include +#include + +#include "simgrid/s4u/Semaphore.hpp" +#include "src/simix/ActorImpl.hpp" + +namespace simgrid { +namespace kernel { +namespace activity { + +class XBT_PUBLIC SemaphoreImpl { +public: + explicit SemaphoreImpl(unsigned int value) : value_(value){}; + ~SemaphoreImpl() = default; + + SemaphoreImpl(SemaphoreImpl const&) = delete; + SemaphoreImpl& operator=(SemaphoreImpl const&) = delete; + + void release(); + bool would_block() { return (value_ <= 0); } + unsigned int get_capacity() { return value_; } + + friend void intrusive_ptr_add_ref(SemaphoreImpl* sem) + { + XBT_ATTRIB_UNUSED auto previous = sem->refcount_.fetch_add(1); + xbt_assert(previous != 0); + } + friend void intrusive_ptr_release(SemaphoreImpl* sem) + { + if (sem->refcount_.fetch_sub(1) == 1) + delete sem; + } + + unsigned int value_; + actor::SynchroList sleeping_; /* list of sleeping actors*/ + +private: + std::atomic_int_fast32_t refcount_{1}; +}; +} // namespace activity +} // namespace kernel +} // namespace simgrid + +#endif /* SIMGRID_KERNEL_ACTIVITY_SEMAPHOREIMPL_HPP_ */ diff --git a/src/s4u/s4u_Semaphore.cpp b/src/s4u/s4u_Semaphore.cpp index 57a62836c4..30eaa89b05 100644 --- a/src/s4u/s4u_Semaphore.cpp +++ b/src/s4u/s4u_Semaphore.cpp @@ -4,24 +4,24 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/msg/msg_private.hpp" -#include "src/simix/smx_synchro_private.hpp" #include "xbt/log.h" #include "simgrid/forward.h" #include "simgrid/s4u/Semaphore.hpp" +#include "src/kernel/activity/SemaphoreImpl.hpp" namespace simgrid { namespace s4u { Semaphore::Semaphore(unsigned int initial_capacity) { - sem_ = simgrid::simix::simcall([initial_capacity] { return SIMIX_sem_init(initial_capacity); }); + sem_ = simgrid::simix::simcall([initial_capacity] { return new kernel::activity::SemaphoreImpl(initial_capacity); }); } Semaphore::~Semaphore() { if (sem_ != nullptr) { - xbt_assert(sem_->sleeping.empty(), "Cannot destroy semaphore since someone is still using it"); + xbt_assert(sem_->sleeping_.empty(), "Cannot destroy semaphore since someone is still using it"); delete sem_; } } @@ -43,17 +43,17 @@ int Semaphore::acquire_timeout(double timeout) void Semaphore::release() { - simgrid::simix::simcall([this] { SIMIX_sem_release(sem_); }); + simgrid::simix::simcall([this] { sem_->release(); }); } int Semaphore::get_capacity() { - return simgrid::simix::simcall([this] { return SIMIX_sem_get_capacity(sem_); }); + return simgrid::simix::simcall([this] { return sem_->get_capacity(); }); } int Semaphore::would_block() { - return simgrid::simix::simcall([this] { return SIMIX_sem_would_block(sem_); }); + return simgrid::simix::simcall([this] { return sem_->would_block(); }); } void intrusive_ptr_add_ref(Semaphore* sem) diff --git a/src/simix/smx_synchro.cpp b/src/simix/smx_synchro.cpp index 7fd7af1ffe..25f766451b 100644 --- a/src/simix/smx_synchro.cpp +++ b/src/simix/smx_synchro.cpp @@ -5,6 +5,7 @@ #include "src/kernel/activity/ConditionVariableImpl.hpp" #include "src/kernel/activity/MutexImpl.hpp" +#include "src/kernel/activity/SemaphoreImpl.hpp" #include "src/kernel/activity/SynchroRaw.hpp" #include "src/kernel/context/Context.hpp" #include "src/simix/smx_synchro_private.hpp" @@ -45,11 +46,11 @@ void SIMIX_synchro_stop_waiting(smx_actor_t process, smx_simcall_t simcall) break; case SIMCALL_SEM_ACQUIRE: - simgrid::xbt::intrusive_erase(simcall_sem_acquire__get__sem(simcall)->sleeping, *process); + simgrid::xbt::intrusive_erase(simcall_sem_acquire__get__sem(simcall)->sleeping_, *process); break; case SIMCALL_SEM_ACQUIRE_TIMEOUT: - simgrid::xbt::intrusive_erase(simcall_sem_acquire_timeout__get__sem(simcall)->sleeping, *process); + simgrid::xbt::intrusive_erase(simcall_sem_acquire_timeout__get__sem(simcall)->sleeping_, *process); simcall_sem_acquire_timeout__set__result(simcall, 1); // signal a timeout break; @@ -78,51 +79,6 @@ void SIMIX_synchro_finish(smx_activity_t synchro) } /******************************** Semaphores **********************************/ -/** @brief Initialize a semaphore */ -smx_sem_t SIMIX_sem_init(unsigned int value) -{ - XBT_IN("(%u)",value); - smx_sem_t sem = new s_smx_sem_t; - sem->value = value; - XBT_OUT(); - return sem; -} - -/** @brief release the semaphore - * - * Unlock a process waiting on the semaphore. - * If no one was blocked, the semaphore capacity is increased by 1. - */ -void SIMIX_sem_release(smx_sem_t sem) -{ - XBT_IN("(%p)",sem); - XBT_DEBUG("Sem release semaphore %p", sem); - if (not sem->sleeping.empty()) { - auto& proc = sem->sleeping.front(); - sem->sleeping.pop_front(); - proc.waiting_synchro = nullptr; - SIMIX_simcall_answer(&proc.simcall); - } else { - sem->value++; - } - XBT_OUT(); -} - -/** @brief Returns true if acquiring this semaphore would block */ -int SIMIX_sem_would_block(smx_sem_t sem) -{ - XBT_IN("(%p)",sem); - XBT_OUT(); - return (sem->value <= 0); -} - -/** @brief Returns the current capacity of the semaphore */ -int SIMIX_sem_get_capacity(smx_sem_t sem) -{ - XBT_IN("(%p)",sem); - XBT_OUT(); - return sem->value; -} static void _SIMIX_sem_wait(smx_sem_t sem, double timeout, smx_actor_t issuer, smx_simcall_t simcall) @@ -131,13 +87,13 @@ static void _SIMIX_sem_wait(smx_sem_t sem, double timeout, smx_actor_t issuer, smx_activity_t synchro = nullptr; XBT_DEBUG("Wait semaphore %p (timeout:%f)", sem, timeout); - if (sem->value <= 0) { + if (sem->value_ <= 0) { synchro = SIMIX_synchro_wait(issuer->host_, timeout); synchro->simcalls_.push_front(simcall); issuer->waiting_synchro = synchro; - sem->sleeping.push_back(*issuer); + sem->sleeping_.push_back(*issuer); } else { - sem->value--; + sem->value_--; SIMIX_simcall_answer(simcall); } XBT_OUT(); diff --git a/src/simix/smx_synchro_private.hpp b/src/simix/smx_synchro_private.hpp index e9844bca2a..33aeb6b869 100644 --- a/src/simix/smx_synchro_private.hpp +++ b/src/simix/smx_synchro_private.hpp @@ -10,17 +10,7 @@ smx_activity_t SIMIX_synchro_wait(sg_host_t smx_host, double timeout); -struct s_smx_sem_t { - unsigned int value; - simgrid::kernel::actor::SynchroList sleeping; /* list of sleeping processes */ -}; - XBT_PRIVATE void SIMIX_synchro_stop_waiting(smx_actor_t process, smx_simcall_t simcall); XBT_PRIVATE void SIMIX_synchro_finish(smx_activity_t synchro); -XBT_PRIVATE XBT_PRIVATE smx_sem_t SIMIX_sem_init(unsigned int value); -XBT_PRIVATE void SIMIX_sem_release(smx_sem_t sem); -XBT_PRIVATE int SIMIX_sem_would_block(smx_sem_t sem); -XBT_PRIVATE int SIMIX_sem_get_capacity(smx_sem_t sem); - #endif diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index b98372e063..2c34a082a3 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -408,6 +408,8 @@ set(SIMIX_SRC src/kernel/activity/MailboxImpl.hpp src/kernel/activity/MutexImpl.cpp src/kernel/activity/MutexImpl.hpp + src/kernel/activity/SemaphoreImpl.cpp + src/kernel/activity/SemaphoreImpl.hpp src/kernel/activity/SleepImpl.cpp src/kernel/activity/SleepImpl.hpp src/kernel/activity/SynchroRaw.cpp -- 2.20.1