/************************** Synchro simcalls **********************************/
XBT_PUBLIC(smx_mutex_t) simcall_mutex_init(void);
XBT_PUBLIC(void) SIMIX_mutex_destroy(smx_mutex_t mutex);
+XBT_PUBLIC(smx_mutex_t) SIMIX_mutex_dup(smx_mutex_t mutex);
XBT_PUBLIC(void) simcall_mutex_lock(smx_mutex_t mutex);
XBT_PUBLIC(int) simcall_mutex_trylock(smx_mutex_t mutex);
XBT_PUBLIC(void) simcall_mutex_unlock(smx_mutex_t mutex);
void SIMIX_mutex_destroy(smx_mutex_t mutex)
{
- delete mutex;
+ if (mutex != nullptr)
+ intrusive_ptr_release(mutex);
+}
+
+XBT_PUBLIC(smx_mutex_t) SIMIX_mutex_dup(smx_mutex_t mutex)
+{
+ if (mutex != nullptr)
+ intrusive_ptr_add_ref(mutex);
+ return mutex;
}
smx_mutex_t simcall_HANDLER_mutex_init(smx_simcall_t simcall)
#ifndef _SIMIX_SYNCHRO_PRIVATE_H
#define _SIMIX_SYNCHRO_PRIVATE_H
+#include <atomic>
+
#include "xbt/base.h"
#include "xbt/swag.h"
#include "xbt/xbt_os_thread.h"
smx_process_t owner = nullptr;
// List of sleeping processes:
xbt_swag_t sleeping = nullptr;
+
+ // boost::intrusive_ptr<Mutex> support:
+ friend void intrusive_ptr_add_ref(Mutex* mutex)
+ {
+ auto previous = ++mutex->refcount_;
+ xbt_assert(previous != 0);
+ (void) previous;
+ }
+ friend void intrusive_ptr_release(Mutex* mutex)
+ {
+ auto count = mutex->refcount_--;
+ if (count == 0)
+ delete mutex;
+ }
+private:
+ std::atomic_int_fast32_t refcount_ { 1 };
};
}