+ XBT_OUT();
+}
+
+/******************************** Semaphores **********************************/
+#define SMX_SEM_NOLIMIT 99999
+/** @brief Initialize a semaphore */
+smx_sem_t SIMIX_sem_init(unsigned int value)
+{
+ XBT_IN("(%d)",value);
+ s_smx_process_t p;
+
+ smx_sem_t sem = xbt_new0(s_smx_sem_t, 1);
+ sem->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup));
+ sem->value = value;
+ XBT_OUT();
+ return sem;
+}
+
+/** @brief Destroys a semaphore */
+void SIMIX_sem_destroy(smx_sem_t sem)
+{
+ XBT_IN("(%p)",sem);
+ XBT_DEBUG("Destroy semaphore %p", sem);
+ if (sem != NULL) {
+ xbt_assert(xbt_swag_size(sem->sleeping) == 0,
+ "Cannot destroy semaphore since someone is still using it");
+ xbt_swag_free(sem->sleeping);
+ xbt_free(sem);
+ }
+ XBT_OUT();
+}
+
+/** @brief release the semaphore
+ *
+ * Unlock a process waiting on the semaphore.
+ * If no one was blocked, the semaphore capacity is increased by 1.
+ */
+void SIMIX_sem_release(smx_sem_t sem)
+{
+ XBT_IN("(%p)",sem);
+ smx_process_t proc;
+
+ XBT_DEBUG("Sem release semaphore %p", sem);
+ if ((proc = xbt_swag_extract(sem->sleeping))) {
+ proc = xbt_swag_extract(sem->sleeping);
+ SIMIX_synchro_destroy(proc->waiting_action);
+ proc->waiting_action = NULL;
+ SIMIX_request_answer(&proc->request);
+ } else if (sem->value < SMX_SEM_NOLIMIT) {
+ sem->value++;
+ }
+ XBT_OUT();
+}
+
+/** @brief Returns true if acquiring this semaphore would block */
+XBT_INLINE int SIMIX_sem_would_block(smx_sem_t sem)
+{
+ XBT_IN("(%p)",sem);
+ XBT_OUT();
+ return (sem->value <= 0);
+}
+
+/** @brief Returns the current capacity of the semaphore */
+int SIMIX_sem_get_capacity(smx_sem_t sem)
+{
+ XBT_IN("(%p)",sem);
+ XBT_OUT();
+ return sem->value;
+}
+
+static void _SIMIX_sem_wait(smx_sem_t sem, double timeout, smx_process_t issuer,
+ smx_req_t req)
+{
+ XBT_IN("(%p, %f, %p, %p)",sem,timeout,issuer,req);
+ smx_action_t sync_act = NULL;
+
+ XBT_DEBUG("Wait semaphore %p (timeout:%f)", sem, timeout);
+ if (sem->value <= 0) {
+ sync_act = SIMIX_synchro_wait(issuer->smx_host, timeout);
+ xbt_fifo_unshift(sync_act->request_list, req);
+ issuer->waiting_action = sync_act;
+ xbt_swag_insert(issuer, sem->sleeping);
+ } else {
+ sem->value--;
+ SIMIX_request_answer(req);
+ }
+ XBT_OUT();
+}
+
+/**
+ * \brief Handle sem acquire requests without timeouts
+ */
+void SIMIX_pre_sem_acquire(smx_req_t req)
+{
+ XBT_IN("(%p)",req);
+ _SIMIX_sem_wait(req->sem_acquire.sem, -1, req->issuer, req);
+ XBT_OUT();
+}
+
+/**
+ * \brief Handle sem acquire requests with timeouts
+ */
+void SIMIX_pre_sem_acquire_timeout(smx_req_t req)
+{
+ XBT_IN("(%p)",req);
+ _SIMIX_sem_wait(req->sem_acquire_timeout.sem,
+ req->sem_acquire_timeout.timeout, req->issuer, req);
+ XBT_OUT();