-xbt_os_cond_t xbt_os_cond_init(void) {
-
- xbt_os_cond_t res = xbt_new0(s_xbt_os_cond_t,1);
-
- memset(& res->waiters_count_lock,0,sizeof(CRITICAL_SECTION));
-
- /* initialize the critical section object */
- InitializeCriticalSection(& res->waiters_count_lock);
-
- res->waiters_count = 0;
-
- /* Create an auto-reset event */
- res->events[SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL);
-
- if(!res->events[SIGNAL]){
- DeleteCriticalSection(& res->waiters_count_lock);
- free(res);
- THROW0(system_error,0,"CreateEvent failed for the signals");
- }
-
- /* Create a manual-reset event. */
- res->events[BROADCAST] = CreateEvent (NULL, TRUE, FALSE,NULL);
-
- if(!res->events[BROADCAST]){
-
- DeleteCriticalSection(& res->waiters_count_lock);
- CloseHandle(res->events[SIGNAL]);
- free(res);
- THROW0(system_error,0,"CreateEvent failed for the broadcasts");
- }
-
- return res;
-}
-
-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)
- THROW0(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]))
- THROW0(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_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]))
- THROW0(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)
- THROW0(system_error,0,"Error while destroying the condition");
+xbt_os_cond_t xbt_os_cond_init(void)
+{
+
+ xbt_os_cond_t res = xbt_new0(s_xbt_os_cond_t, 1);
+
+ memset(&res->waiters_count_lock, 0, sizeof(CRITICAL_SECTION));
+
+ /* initialize the critical section object */
+ InitializeCriticalSection(&res->waiters_count_lock);
+
+ res->waiters_count = 0;
+
+ /* Create an auto-reset event */
+ res->events[SIGNAL] = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ if (!res->events[SIGNAL]) {
+ DeleteCriticalSection(&res->waiters_count_lock);
+ free(res);
+ THROW0(system_error, 0, "CreateEvent failed for the signals");
+ }
+
+ /* Create a manual-reset event. */
+ res->events[BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (!res->events[BROADCAST]) {
+
+ DeleteCriticalSection(&res->waiters_count_lock);
+ CloseHandle(res->events[SIGNAL]);
+ free(res);
+ THROW0(system_error, 0, "CreateEvent failed for the broadcasts");
+ }
+
+ return res;
+}
+
+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)
+ THROW0(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]))
+ THROW0(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 {
+ DEBUG3("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:
+ THROW3(timeout_error, GetLastError(),
+ "condition %p (mutex %p) wasn't signaled before timeout (%f)",
+ cond, mutex, delay);
+ case WAIT_FAILED:
+ THROW0(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]))
+ THROW0(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]))
+ THROW0(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)
+ THROW0(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)
+ THROW1(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))) {
+ THROW1(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)
+ THROW0(arg_error, EINVAL, "Cannot acquire the NULL semaphore");
+
+ /* wait failure */
+ if (WAIT_OBJECT_0 != WaitForSingleObject(sem->h, INFINITE))
+ THROW1(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)
+ THROW0(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:
+ THROW2(timeout_error, GetLastError(),
+ "semaphore %p wasn't signaled before timeout (%f)", sem,
+ timeout);
+ return;
+
+ default:
+ THROW3(system_error, GetLastError(),
+ "WaitForSingleObject(%p,%f) failed: %s", sem, timeout,
+ strerror(GetLastError()));
+ }
+ }
+}
+
+void xbt_os_sem_release(xbt_os_sem_t sem)
+{
+ if (!sem)
+ THROW0(arg_error, EINVAL, "Cannot release the NULL semaphore");
+
+ if (!ReleaseSemaphore(sem->h, 1, NULL))
+ THROW1(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)
+ THROW0(arg_error, EINVAL, "Cannot destroy the NULL semaphore");
+
+ if (!CloseHandle(sem->h))
+ THROW1(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)
+ THROW0(arg_error, EINVAL, "Cannot get the value of the NULL semaphore");
+
+ EnterCriticalSection(&(sem->value_lock));
+ *svalue = sem->value;
+ LeaveCriticalSection(&(sem->value_lock));