/* FIXME: that's a poor man's implementation: we should take the message exchanges into account */
static void action_barrier(const char *const *action)
{
- static simgrid::s4u::Mutex *mutex = NULL;
+ static simgrid::s4u::MutexPtr mutex = nullptr;
static simgrid::s4u::ConditionVariable *cond = NULL;
static int processes_arrived_sofar = 0;
- if (mutex == NULL) { // first arriving on the barrier
- mutex = new simgrid::s4u::Mutex();
+ if (mutex == nullptr) { // first arriving on the barrier
+ mutex = simgrid::s4u::Mutex::createMutex();
cond = new simgrid::s4u::ConditionVariable();
processes_arrived_sofar = 0;
}
processes_arrived_sofar--;
if (processes_arrived_sofar<=0) {
delete cond;
- delete mutex;
- mutex = NULL;
+ mutex = nullptr;
}
}
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
-static void worker(simgrid::s4u::Mutex mutex, int& result)
+static void worker(simgrid::s4u::MutexPtr mutex, int& result)
{
// Do the calculation
simgrid::s4u::this_actor::execute(1000);
// lock the mutex before enter in the critical section
- std::lock_guard<simgrid::s4u::Mutex> lock(mutex);
+ std::lock_guard<simgrid::s4u::Mutex> lock(*mutex);
XBT_INFO("Hello s4u, I'm ready to compute");
// And finaly add it to the results
XBT_INFO("I'm done, good bye");
}
-static void workerLockGuard(simgrid::s4u::Mutex mutex, int& result)
+static void workerLockGuard(simgrid::s4u::MutexPtr mutex, int& result)
{
simgrid::s4u::this_actor::execute(1000);
// Simply use the std::lock_guard like this
- std::lock_guard<simgrid::s4u::Mutex> lock(mutex);
+ std::lock_guard<simgrid::s4u::Mutex> lock(*mutex);
// then you are in a safe zone
XBT_INFO("Hello s4u, I'm ready to compute");
static void master()
{
int result = 0;
- simgrid::s4u::Mutex mutex;
+ simgrid::s4u::MutexPtr mutex = simgrid::s4u::Mutex::createMutex();
for (int i = 0; i < NB_ACTOR * 2 ; i++) {
// To create a worker use the static method simgrid::s4u::Actor.
XBT_PUBLIC_CLASS Mutex {
friend ConditionVariable;
+private:
+ friend simgrid::simix::Mutex;
+ simgrid::simix::Mutex* mutex_;
+ Mutex(simgrid::simix::Mutex* mutex) : mutex_(mutex) {}
public:
- Mutex() :
- mutex_(simcall_mutex_init()) {}
- Mutex(simgrid::simix::Mutex* mutex) : mutex_(SIMIX_mutex_ref(mutex)) {}
- ~Mutex()
- {
- SIMIX_mutex_unref(mutex_);
- }
- // Copy+move (with the copy-and-swap idiom):
- Mutex(Mutex const& mutex) : mutex_(SIMIX_mutex_ref(mutex.mutex_)) {}
- friend void swap(Mutex& first, Mutex& second)
+ friend void intrusive_ptr_add_ref(Mutex* mutex)
{
- using std::swap;
- swap(first.mutex_, second.mutex_);
+ xbt_assert(mutex);
+ SIMIX_mutex_ref(mutex->mutex_);
}
- Mutex& operator=(Mutex mutex)
+ friend void intrusive_ptr_release(Mutex* mutex)
{
- swap(*this, mutex);
- return *this;
- }
- Mutex(Mutex&& mutex) : mutex_(nullptr)
- {
- swap(*this, mutex);
+ xbt_assert(mutex);
+ SIMIX_mutex_unref(mutex->mutex_);
}
+ using Ptr = boost::intrusive_ptr<Mutex>;
- bool valid() const
- {
- return mutex_ != nullptr;
- }
+ // No copy:
+ Mutex(Mutex const&) = delete;
+ Mutex& operatori(Mutex const&) = delete;
+
+ static Ptr createMutex();
public:
void lock();
void unlock();
bool try_lock();
-
-private:
- simgrid::simix::Mutex* mutex_;
};
+using MutexPtr = Mutex::Ptr;
+
}} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_MUTEX_HPP */
#include "xbt/log.h"
#include "src/msg/msg_private.h"
-#include "src/simix/smx_network_private.h"
+#include "src/simix/smx_synchro_private.h"
#include "simgrid/s4u/mutex.hpp"
namespace simgrid {
namespace s4u {
-void Mutex::lock() {
+void Mutex::lock()
+{
simcall_mutex_lock(mutex_);
}
-void Mutex::unlock() {
+void Mutex::unlock()
+{
simcall_mutex_unlock(mutex_);
}
-bool Mutex::try_lock() {
+bool Mutex::try_lock()
+{
return simcall_mutex_trylock(mutex_);
}
+MutexPtr Mutex::createMutex()
+{
+ smx_mutex_t mutex = simcall_mutex_init();
+ return MutexPtr(&mutex->mutex(), false);
+}
+
}
}
namespace simgrid {
namespace simix {
-Mutex::Mutex()
+Mutex::Mutex() : mutex_(this)
{
XBT_IN("(%p)", this);
// Useful to initialize sleeping swag:
#include <atomic>
+#include <simgrid/s4u/mutex.hpp>
+
#include "xbt/base.h"
#include "xbt/swag.h"
#include "xbt/xbt_os_thread.h"
if (count == 0)
delete mutex;
}
+
+ simgrid::s4u::Mutex& mutex() { return mutex_; }
+
private:
std::atomic_int_fast32_t refcount_ { 1 };
+ simgrid::s4u::Mutex mutex_;
};
}