+/**
+ * \brief Handles a mutex lock simcall.
+ * \param simcall the simcall
+ */
+void SIMIX_pre_mutex_lock(smx_simcall_t simcall)
+{
+ XBT_IN("(%p)",simcall);
+ /* FIXME: check where to validate the arguments */
+ smx_action_t sync_act = NULL;
+ smx_mutex_t mutex = simcall->mutex_lock.mutex;
+ smx_process_t process = simcall->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->simcalls, simcall);
+ simcall->issuer->waiting_action = sync_act;
+ xbt_swag_insert(simcall->issuer, mutex->sleeping);
+ } else {
+ /* mutex free */
+ mutex->locked = 1;
+ mutex->owner = simcall->issuer;
+ SIMIX_simcall_answer(simcall);
+ }
+ XBT_OUT();
+}
+
+/**
+ * \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)
+{
+ XBT_IN("(%p, %p)",mutex,issuer);
+ if (mutex->locked){
+ XBT_OUT();
+ return 0;
+ }
+
+ mutex->locked = 1;
+ mutex->owner = issuer;
+ XBT_OUT();
+ 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)
+{
+ XBT_IN("(%p, %p)",mutex,issuer);
+ smx_process_t p; /*process to wake up */
+
+ /* If the mutex is not owned by the issuer do nothing */
+ if (issuer != mutex->owner){
+ XBT_OUT();
+ 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_simcall_answer(&p->simcall);
+ } else {
+ /* nobody to wake up */
+ mutex->locked = 0;
+ mutex->owner = NULL;
+ }
+ XBT_OUT();
+}
+
+/**
+ * \brief Destroys a mutex.
+ *
+ * Destroys and frees the mutex's memory.
+ * \param mutex A mutex
+ */
+void SIMIX_mutex_destroy(smx_mutex_t mutex)