From: Millian Poquet Date: Mon, 1 Oct 2018 17:27:03 +0000 (+0200) Subject: [s4u] implement semaphore as direct SIMIX wrapper X-Git-Tag: v3_21~15^2^2~1 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/009fecfd613cf13e7939dd650cce1625d5c7329f?ds=sidebyside [s4u] implement semaphore as direct SIMIX wrapper --- diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index 86a28bd641..fd0ab86093 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -74,6 +74,13 @@ typedef boost::intrusive_ptr MutexPtr; class NetZone; class VirtualMachine; class File; + +class Semaphore; +/** Smart pointer to a simgrid::s4u::Semaphore */ +typedef boost::intrusive_ptr SemaphorePtr; +XBT_PUBLIC void intrusive_ptr_release(Semaphore* m); +XBT_PUBLIC void intrusive_ptr_add_ref(Semaphore* m); + class Storage; } // namespace s4u diff --git a/include/simgrid/s4u.hpp b/include/simgrid/s4u.hpp index 485ed2d433..d3182a50ba 100644 --- a/include/simgrid/s4u.hpp +++ b/include/simgrid/s4u.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/include/simgrid/s4u/Semaphore.hpp b/include/simgrid/s4u/Semaphore.hpp new file mode 100644 index 0000000000..442b147eb1 --- /dev/null +++ b/include/simgrid/s4u/Semaphore.hpp @@ -0,0 +1,54 @@ +/* Copyright (c) 2006-2018. 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_S4U_SEMAPHORE_HPP +#define SIMGRID_S4U_SEMAPHORE_HPP + +#include +#include + +namespace simgrid { +namespace s4u { + +/** @brief A classical semaphore, but blocking in the simulation world + * @ingroup s4u_api + * + * It is strictly impossible to use a real semaphore, such as + * sem_init, + * because it would block the whole simulation. + * Instead, you should use the present class, that offers a very similar interface. + * + * As for any S4U object, Semaphores are using the @ref s4u_raii "RAII idiom" for memory management. + * Use createSemaphore() to get a ::SemaphorePtr to a newly created semaphore + * and only manipulate ::SemaphorePtr. + * + */ +class XBT_PUBLIC Semaphore { + smx_sem_t sem_; + std::atomic_int_fast32_t refcount_{0}; + + explicit Semaphore(unsigned int initial_capacity); + ~Semaphore(); + + friend void intrusive_ptr_add_ref(Semaphore* sem); + friend void intrusive_ptr_release(Semaphore* sem); + +public: + // No copy: + /** You cannot create a new semaphore by copying an existing one. Use SemaphorePtr instead */ + Semaphore(Semaphore const&) = delete; + /** You cannot create a new semaphore by value assignment either. Use SemaphorePtr instead */ + Semaphore& operator=(Semaphore const&) = delete; + + /** Constructs a new semaphore */ + static SemaphorePtr create(unsigned int initial_capacity); + + void acquire(); + void release(); +}; + +}} // namespace simgrid::s4u + +#endif /* SIMGRID_S4U_SEMAPHORE_HPP */ diff --git a/src/s4u/s4u_Semaphore.cpp b/src/s4u/s4u_Semaphore.cpp new file mode 100644 index 0000000000..191094aeb9 --- /dev/null +++ b/src/s4u/s4u_Semaphore.cpp @@ -0,0 +1,56 @@ +/* Copyright (c) 2006-201. 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/msg/msg_private.hpp" +#include "src/simix/smx_synchro_private.hpp" +#include "xbt/log.h" + +#include "simgrid/s4u/Semaphore.hpp" + +namespace simgrid { +namespace s4u { + +Semaphore::Semaphore(unsigned int initial_capacity) +{ + sem_ = simgrid::simix::simcall([initial_capacity] { return SIMIX_sem_init(initial_capacity); }); +} + +Semaphore::~Semaphore() +{ + SIMIX_sem_destroy(sem_); +} + +SemaphorePtr Semaphore::create(unsigned int initial_capacity) +{ + return SemaphorePtr(new Semaphore(initial_capacity)); +} + +void Semaphore::acquire() +{ + simcall_sem_acquire(sem_); +} + +void Semaphore::release() +{ + simgrid::simix::simcall([this] { SIMIX_sem_release(sem_); }); +} + +void intrusive_ptr_add_ref(Semaphore* sem) +{ + xbt_assert(sem); + sem->refcount_.fetch_add(1, std::memory_order_relaxed); +} + +void intrusive_ptr_release(Semaphore* sem) +{ + xbt_assert(sem); + if (sem->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete sem; + } +} + +} +} diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index f580465713..3cbd633fb6 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -440,6 +440,7 @@ set(S4U_SRC src/s4u/s4u_Mailbox.cpp src/s4u/s4u_Mutex.cpp src/s4u/s4u_Netzone.cpp + src/s4u/s4u_Semaphore.cpp src/s4u/s4u_Storage.cpp ) @@ -707,6 +708,7 @@ set(headers_to_install include/simgrid/s4u/Mailbox.hpp include/simgrid/s4u/Mutex.hpp include/simgrid/s4u/NetZone.hpp + include/simgrid/s4u/Semaphore.hpp include/simgrid/s4u/Storage.hpp include/simgrid/s4u/VirtualMachine.hpp include/simgrid/s4u.hpp