+void xbt_os_cond_wait(xbt_os_cond_t cond, xbt_os_mutex_t mutex)
+{
+
+ unsigned long wait_result;
+ int is_last_waiter;
+
+ /* lock the threads counter and increment it */
+ EnterCriticalSection(&cond->waiters_count_lock);
+ cond->waiters_count++;
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ /* unlock the mutex associate with the condition */
+ LeaveCriticalSection(&mutex->lock);
+
+ /* wait for a signal (broadcast or no) */
+ wait_result = WaitForMultipleObjects(2, cond->events, FALSE, INFINITE);
+
+ if (wait_result == WAIT_FAILED)
+ THROWF(system_error, 0,
+ "WaitForMultipleObjects failed, so we cannot wait on the condition");
+
+ /* we have a signal lock the condition */
+ EnterCriticalSection(&cond->waiters_count_lock);
+ cond->waiters_count--;
+
+ /* it's the last waiter or it's a broadcast ? */
+ is_last_waiter = ((wait_result == WAIT_OBJECT_0 + BROADCAST - 1)
+ && (cond->waiters_count == 0));
+
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ /* yes it's the last waiter or it's a broadcast
+ * only reset the manual event (the automatic event is reset in the WaitForMultipleObjects() function
+ * by the system.
+ */
+ if (is_last_waiter)
+ if (!ResetEvent(cond->events[BROADCAST]))
+ THROWF(system_error, 0, "ResetEvent failed");
+
+ /* relock the mutex associated with the condition in accordance with the posix thread specification */
+ EnterCriticalSection(&mutex->lock);
+}
+
+void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex,
+ double delay)
+{
+
+ unsigned long wait_result = WAIT_TIMEOUT;
+ int is_last_waiter;
+ unsigned long end = (unsigned long) (delay * 1000);
+
+
+ if (delay < 0) {
+ xbt_os_cond_wait(cond, mutex);
+ } else {
+ XBT_DEBUG("xbt_cond_timedwait(%p,%p,%lu)", &(cond->events),
+ &(mutex->lock), end);
+
+ /* lock the threads counter and increment it */
+ EnterCriticalSection(&cond->waiters_count_lock);
+ cond->waiters_count++;
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ /* unlock the mutex associate with the condition */
+ LeaveCriticalSection(&mutex->lock);
+ /* wait for a signal (broadcast or no) */
+
+ wait_result = WaitForMultipleObjects(2, cond->events, FALSE, end);
+
+ switch (wait_result) {
+ case WAIT_TIMEOUT:
+ THROWF(timeout_error, GetLastError(),
+ "condition %p (mutex %p) wasn't signaled before timeout (%f)",
+ cond, mutex, delay);
+ case WAIT_FAILED:
+ THROWF(system_error, GetLastError(),
+ "WaitForMultipleObjects failed, so we cannot wait on the condition");
+ }
+
+ /* we have a signal lock the condition */
+ EnterCriticalSection(&cond->waiters_count_lock);
+ cond->waiters_count--;
+
+ /* it's the last waiter or it's a broadcast ? */
+ is_last_waiter = ((wait_result == WAIT_OBJECT_0 + BROADCAST - 1)
+ && (cond->waiters_count == 0));
+
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ /* yes it's the last waiter or it's a broadcast
+ * only reset the manual event (the automatic event is reset in the WaitForMultipleObjects() function
+ * by the system.
+ */
+ if (is_last_waiter)
+ if (!ResetEvent(cond->events[BROADCAST]))
+ THROWF(system_error, 0, "ResetEvent failed");
+
+ /* relock the mutex associated with the condition in accordance with the posix thread specification */
+ EnterCriticalSection(&mutex->lock);
+ }
+ /*THROW_UNIMPLEMENTED; */
+}
+
+void xbt_os_cond_signal(xbt_os_cond_t cond)
+{
+ int have_waiters;
+
+ EnterCriticalSection(&cond->waiters_count_lock);
+ have_waiters = cond->waiters_count > 0;
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ if (have_waiters)
+ if (!SetEvent(cond->events[SIGNAL]))
+ THROWF(system_error, 0, "SetEvent failed");
+
+ xbt_os_thread_yield();
+}
+
+void xbt_os_cond_broadcast(xbt_os_cond_t cond)
+{
+ int have_waiters;
+
+ EnterCriticalSection(&cond->waiters_count_lock);
+ have_waiters = cond->waiters_count > 0;
+ LeaveCriticalSection(&cond->waiters_count_lock);
+
+ if (have_waiters)
+ SetEvent(cond->events[BROADCAST]);
+}
+
+void xbt_os_cond_destroy(xbt_os_cond_t cond)
+{
+ int error = 0;
+
+ if (!cond)
+ return;
+
+ if (!CloseHandle(cond->events[SIGNAL]))
+ error = 1;
+
+ if (!CloseHandle(cond->events[BROADCAST]))
+ error = 1;
+
+ DeleteCriticalSection(&cond->waiters_count_lock);
+
+ xbt_free(cond);
+
+ if (error)
+ THROWF(system_error, 0, "Error while destroying the condition");
+}
+
+typedef struct xbt_os_sem_ {
+ HANDLE h;
+ unsigned int value;
+ CRITICAL_SECTION value_lock; /* protect access to value of the semaphore */
+} s_xbt_os_sem_t;
+
+#ifndef INT_MAX
+# define INT_MAX 32767 /* let's be safe by underestimating this value: this is for 16bits only */