-smx_mutex_t SIMIX_mutex_init()
-{
- smx_mutex_t m = xbt_new0(s_smx_mutex_t,1);
- s_smx_process_t p; /* useful to initialize sleeping swag */
- /* structures initialization */
- m->using = 0;
- m->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup));
- return m;
-}
-
-void SIMIX_mutex_lock(smx_mutex_t mutex)
-{
- smx_process_t self = SIMIX_process_self();
-
- xbt_assert0((mutex != NULL), "Invalid parameters");
-
- if (mutex->using) {
- /* somebody using the mutex, block */
- xbt_swag_insert(self, mutex->sleeping);
- self->simdata->mutex = mutex;
- __SIMIX_process_block(-1);
- self->simdata->mutex = NULL;
- mutex->using = 1;
- }
- else {
- /* mutex free */
- mutex->using = 1;
- }
- return;
-}
-/* return 1 if the process got the mutex, else 0. */
-int SIMIX_mutex_trylock(smx_mutex_t mutex)
-{
- xbt_assert0((mutex != NULL), "Invalid parameters");
-
- if (mutex->using)
- return 0;
- else {
- mutex->using = 1;
- return 1;
- }
-}
-
-void SIMIX_mutex_unlock(smx_mutex_t mutex)
-{
- smx_process_t p; /*process to wake up */
-
- xbt_assert0((mutex != NULL), "Invalid parameters");
-
- if (xbt_swag_size(mutex->sleeping) > 0) {
- p = xbt_swag_extract(mutex->sleeping);
- mutex->using = 0;
- __SIMIX_process_unblock(p);
- }
- else {
- /* nobody to wape up */
- mutex->using = 0;
- }
- return;
+
+/**
+ * \brief Initialize a mutex.
+ *
+ * Allocs and creates the data for the mutex.
+ * \return A mutex
+ */
+smx_mutex_t SIMIX_mutex_init(void)
+{
+ s_smx_process_t p; /* useful to initialize sleeping swag */
+
+ smx_mutex_t mutex = xbt_new0(s_smx_mutex_t, 1);
+ mutex->locked = 0;
+ mutex->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup));
+ return mutex;
+}
+
+/**
+ * \brief Handle mutex lock request
+ * \param req The request
+ */
+void SIMIX_pre_mutex_lock(smx_req_t req)
+{
+ /* FIXME: check where to validate the arguments */
+ smx_action_t sync_act = NULL;
+ smx_mutex_t mutex = req->mutex_lock.mutex;
+ smx_process_t process = req->issuer;
+
+ if (mutex->locked) {
+ /* FIXME: check if the host is active ? */
+ /* Somebody using the mutex, use a synchro action to get host failures */
+ sync_act = SIMIX_synchro_wait(process->smx_host, -1);
+ xbt_fifo_push(sync_act->request_list, req);
+ req->issuer->waiting_action = sync_act;
+ xbt_swag_insert(req->issuer, mutex->sleeping);
+ } else {
+ /* mutex free */
+ mutex->locked = 1;
+ mutex->owner = req->issuer;
+ SIMIX_request_answer(req);
+ }
+}
+
+/**
+ * \brief Tries to lock a mutex.
+ *
+ * Tries to lock a mutex, return 1 if the mutex is unlocked, else 0.
+ * This function does not block and wait for the mutex to be unlocked.
+ * \param mutex The mutex
+ * \param issuer The process that tries to acquire the mutex
+ * \return 1 - mutex free, 0 - mutex used
+ */
+int SIMIX_mutex_trylock(smx_mutex_t mutex, smx_process_t issuer)
+{
+ if (mutex->locked)
+ return 0;
+
+ mutex->locked = 1;
+ mutex->owner = issuer;
+ return 1;
+}
+
+/**
+ * \brief Unlocks a mutex.
+ *
+ * Unlocks the mutex and gives it to a process waiting for it.
+ * If the unlocker is not the owner of the mutex nothing happens.
+ * If there are no process waiting, it sets the mutex as free.
+ * \param mutex The mutex
+ * \param issuer The process trying to unlock the mutex
+ */
+void SIMIX_mutex_unlock(smx_mutex_t mutex, smx_process_t issuer)
+{
+ smx_process_t p; /*process to wake up */
+
+ /* If the mutex is not owned by the issuer do nothing */
+ if (issuer != mutex->owner)
+ return;
+
+ if (xbt_swag_size(mutex->sleeping) > 0) {
+ p = xbt_swag_extract(mutex->sleeping);
+ SIMIX_synchro_destroy(p->waiting_action);
+ p->waiting_action = NULL;
+ mutex->owner = p;
+ SIMIX_request_answer(&p->request);
+ } else {
+ /* nobody to wake up */
+ mutex->locked = 0;
+ mutex->owner = NULL;
+ }