+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 */
+#endif
+
+xbt_os_sem_t xbt_os_sem_init(unsigned int value)
+{
+ xbt_os_sem_t res;
+
+ if (value > INT_MAX)
+ THROWF(arg_error, value,
+ "Semaphore initial value too big: %ud cannot be stored as a signed int",
+ value);
+
+ res = (xbt_os_sem_t) xbt_new0(s_xbt_os_sem_t, 1);
+
+ if (!(res->h = CreateSemaphore(NULL, value, (long) INT_MAX, NULL))) {
+ THROWF(system_error, GetLastError(), "CreateSemaphore() failed: %s",
+ strerror(GetLastError()));
+ return NULL;
+ }
+
+ res->value = value;
+
+ InitializeCriticalSection(&(res->value_lock));
+
+ return res;
+}
+
+void xbt_os_sem_acquire(xbt_os_sem_t sem)
+{
+ if (!sem)
+ THROWF(arg_error, EINVAL, "Cannot acquire the NULL semaphore");
+
+ /* wait failure */
+ if (WAIT_OBJECT_0 != WaitForSingleObject(sem->h, INFINITE))
+ THROWF(system_error, GetLastError(),
+ "WaitForSingleObject() failed: %s", strerror(GetLastError()));
+ EnterCriticalSection(&(sem->value_lock));
+ sem->value--;
+ LeaveCriticalSection(&(sem->value_lock));
+}
+
+void xbt_os_sem_timedacquire(xbt_os_sem_t sem, double timeout)
+{
+ long seconds;
+ long milliseconds;
+ double end = timeout + xbt_os_time();
+
+ if (!sem)
+ THROWF(arg_error, EINVAL, "Cannot acquire the NULL semaphore");
+
+ if (timeout < 0) {
+ xbt_os_sem_acquire(sem);
+ } else { /* timeout can be zero <-> try acquire ) */
+
+
+ seconds = (long) floor(end);
+ milliseconds = (long) ((end - seconds) * 1000);
+ milliseconds += (seconds * 1000);
+
+ switch (WaitForSingleObject(sem->h, milliseconds)) {
+ case WAIT_OBJECT_0:
+ EnterCriticalSection(&(sem->value_lock));
+ sem->value--;
+ LeaveCriticalSection(&(sem->value_lock));
+ return;
+
+ case WAIT_TIMEOUT:
+ THROWF(timeout_error, GetLastError(),
+ "semaphore %p wasn't signaled before timeout (%f)", sem,
+ timeout);
+ return;
+
+ default:
+ THROWF(system_error, GetLastError(),
+ "WaitForSingleObject(%p,%f) failed: %s", sem, timeout,
+ strerror(GetLastError()));
+ }
+ }
+}
+
+void xbt_os_sem_release(xbt_os_sem_t sem)
+{
+ if (!sem)
+ THROWF(arg_error, EINVAL, "Cannot release the NULL semaphore");
+
+ if (!ReleaseSemaphore(sem->h, 1, NULL))
+ THROWF(system_error, GetLastError(), "ReleaseSemaphore() failed: %s",
+ strerror(GetLastError()));
+ EnterCriticalSection(&(sem->value_lock));
+ sem->value++;
+ LeaveCriticalSection(&(sem->value_lock));
+}
+
+void xbt_os_sem_destroy(xbt_os_sem_t sem)
+{
+ if (!sem)
+ THROWF(arg_error, EINVAL, "Cannot destroy the NULL semaphore");
+
+ if (!CloseHandle(sem->h))
+ THROWF(system_error, GetLastError(), "CloseHandle() failed: %s",
+ strerror(GetLastError()));
+
+ DeleteCriticalSection(&(sem->value_lock));
+
+ xbt_free(sem);
+
+}
+
+void xbt_os_sem_get_value(xbt_os_sem_t sem, int *svalue)
+{
+ if (!sem)
+ THROWF(arg_error, EINVAL,
+ "Cannot get the value of the NULL semaphore");
+
+ EnterCriticalSection(&(sem->value_lock));
+ *svalue = sem->value;
+ LeaveCriticalSection(&(sem->value_lock));
+}
+
+