Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
This change concerne the usage of the semaphore object instead the variable condition...
authorcherierm <cherierm@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 22 Oct 2007 08:51:31 +0000 (08:51 +0000)
committercherierm <cherierm@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 22 Oct 2007 08:51:31 +0000 (08:51 +0000)
The xbt_os_sem_t type represents a semaphore and you' ll find its declaration in the header xbt_os_thread.h and its implementation in the file xbt_os_thread.c.
The file portable.h is modified to declare the function gettimeofday() used by many several other functions such the function xbt_os_sem_timedwait() declared in
the header xbt_os_thread.h. The context structure declared in the header context_private.h is modified to use the semaphore instead the condition variable.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@4838 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/include/xbt/xbt_os_thread.h
src/portable.h
src/win32/compiler/visualc.h
src/xbt/context.c
src/xbt/context_private.h
src/xbt/xbt_os_thread.c

index e42d2ec..b39fcec 100644 (file)
 #include "xbt/misc.h" /* SG_BEGIN_DECL */
 #include "xbt/function_types.h"
 
 #include "xbt/misc.h" /* SG_BEGIN_DECL */
 #include "xbt/function_types.h"
 
+#ifndef WIN32 /* HAVE_SEMAPHOR_H */
+#include <semaphore.h>
+#endif
+
+
 SG_BEGIN_DECL()
 
 /** @addtogroup XBT_thread
 SG_BEGIN_DECL()
 
 /** @addtogroup XBT_thread
@@ -61,6 +66,19 @@ SG_BEGIN_DECL()
   XBT_PUBLIC(void)          xbt_os_cond_signal(xbt_os_cond_t cond);
   XBT_PUBLIC(void)          xbt_os_cond_broadcast(xbt_os_cond_t cond);
   XBT_PUBLIC(void)          xbt_os_cond_destroy(xbt_os_cond_t cond);
   XBT_PUBLIC(void)          xbt_os_cond_signal(xbt_os_cond_t cond);
   XBT_PUBLIC(void)          xbt_os_cond_broadcast(xbt_os_cond_t cond);
   XBT_PUBLIC(void)          xbt_os_cond_destroy(xbt_os_cond_t cond);
+  
+   /** \brief Semaphore data type (opaque structure) */
+  typedef struct xbt_os_sem_* xbt_os_sem_t;
+
+  XBT_PUBLIC(xbt_os_sem_t) xbt_os_sem_init(int pshared, unsigned int value);
+  XBT_PUBLIC(xbt_os_sem_t) xbt_os_sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
+  XBT_PUBLIC(void) xbt_os_sem_wait(xbt_os_sem_t sem);
+  XBT_PUBLIC(void) xbt_os_sem_timedwait(xbt_os_sem_t sem,const struct timespec* abs_timeout);
+  XBT_PUBLIC(void) xbt_os_sem_post(xbt_os_sem_t sem);
+  XBT_PUBLIC(void) xbt_os_sem_close(xbt_os_sem_t sem);
+  XBT_PUBLIC(void) xbt_os_sem_destroy(xbt_os_sem_t sem);
+  XBT_PUBLIC(void) xbt_os_sem_get_value(xbt_os_sem_t sem, int* svalue);
 
 /** @} */
 
 
 /** @} */
 
index f56b81d..537d24c 100644 (file)
@@ -156,4 +156,11 @@ extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);
 void hexa_print(const char*name, unsigned char *data, int size);
 const char *hexa_str(unsigned char *data, int size, int downside);
 
 void hexa_print(const char*name, unsigned char *data, int size);
 const char *hexa_str(unsigned char *data, int size, int downside);
 
+
+#if defined(WIN32)
+/* Visual C++ does not implements the gettimeofday() function */
+XBT_PUBLIC(int)
+gettimeofday(struct timeval *tv, struct timezone *tz);
+#endif
+
 #endif /* GRAS_PORTABLE_H */
 #endif /* GRAS_PORTABLE_H */
index cb19849..a8af217 100644 (file)
@@ -399,8 +399,6 @@ the double. For now, GRAS requires the structures to be compacted. */
  * Replace winsock2.h,ws2tcpip.h and winsock.h header files */
 #include <windows.h>
 
  * Replace winsock2.h,ws2tcpip.h and winsock.h header files */
 #include <windows.h>
 
-/* types */
-typedef unsigned int uint32_t;
 
 /* Choose setjmp as exception implementation */
 #ifndef __EX_MCTX_SJLJ__
 
 /* Choose setjmp as exception implementation */
 #ifndef __EX_MCTX_SJLJ__
@@ -408,6 +406,50 @@ typedef unsigned int uint32_t;
 #endif 
 
 
 #endif 
 
 
+
+#include <sys/stat.h>
+
+#define S_IWUSR _S_IWRITE
+#define S_IRUSR _S_IREAD
+
+#define HAVE_STRUCT_TIMESPEC           0
+
+#define HAVE_STRUCT_TM                         1
+
+#define HAVE_GETTIMEOFDAY                      1
+
+#ifdef _WIN32_WINNT
+       #if _WIN32_WINNT < 0x0400
+               #undef _WIN32_WINNT
+               #define _WIN32_WINNT 0x0400
+       #endif
+#else
+       #define _WIN32_WINNT 0x0400     
+#endif
+
+/* Visual C++ does not declare the ssize_t type */
 typedef int ssize_t;
 
 typedef int ssize_t;
 
+/* Visual C++ does not declare the mode_t type */
+typedef unsigned int mode_t;
+
+/* Visual C++ does not declare the uint32_t type */
+typedef unsigned int uint32_t;
+
+/* Visual C++ doesn't declare the structure timespec */
+struct timespec 
+{
+       long    tv_sec;        /* seconds                                                       */
+       long    tv_nsec;       /* nanoseconds                                           */
+};
+
+/* Visual C++ doesn't declare the structure timezone :
+ *(a structure used to indicate the local time zone)
+ */
+struct timezone 
+{
+       int tz_minuteswest;     /* of Greenwich                                         */
+    int tz_dsttime;            /* type of dst correction to apply      */
+};
+
 #endif /* #ifndef __XBT_VISUALC_COMPILER_CONFIG_H__ */
 #endif /* #ifndef __XBT_VISUALC_COMPILER_CONFIG_H__ */
index 4629739..4f4edca 100644 (file)
@@ -25,19 +25,6 @@ static xbt_context_t init_context = NULL;
 static xbt_swag_t context_to_destroy = NULL;
 static xbt_swag_t context_living = NULL;
 
 static xbt_swag_t context_to_destroy = NULL;
 static xbt_swag_t context_living = NULL;
 
-#ifdef CONTEXT_THREADS
-static xbt_os_mutex_t creation_mutex;
-static xbt_os_cond_t creation_cond;
-static xbt_os_mutex_t master_mutex;
-static xbt_os_cond_t master_cond;
-
-static xbt_os_thread_t current_thread_id;
-
-static int is_main_thread(void) {
-   return xbt_os_thread_self() == current_thread_id;
-}
-
-#endif
 
 
 /********************/
 
 
 /********************/
@@ -62,6 +49,27 @@ static void _context_ex_terminate(xbt_ex_t * e)
 }
 #endif
 
 }
 #endif
 
+
+static void 
+schedule(xbt_context_t c);
+
+static void 
+unschedule(xbt_context_t c);
+
+
+static void 
+schedule(xbt_context_t c) 
+{
+       xbt_os_sem_post(c->begin);      
+       xbt_os_sem_wait(c->end);        
+}
+
+static void unschedule(xbt_context_t c) 
+{
+       xbt_os_sem_post(c->end);                
+       xbt_os_sem_wait(c->begin);
+}
+
 /** \name Functions 
  *  \ingroup XBT_context
  */
 /** \name Functions 
  *  \ingroup XBT_context
  */
@@ -80,19 +88,8 @@ void xbt_context_init(void)
       xbt_swag_new(xbt_swag_offset(*current_context, hookup));
     context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));
     xbt_swag_insert(init_context, context_living);
       xbt_swag_new(xbt_swag_offset(*current_context, hookup));
     context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));
     xbt_swag_insert(init_context, context_living);
-
-#ifdef CONTEXT_THREADS
-    /* only used during the creation of the processes */
-    creation_mutex = xbt_os_mutex_init();
-    creation_cond = xbt_os_cond_init();
-
-    /* used to schedule/unschedule the processes */
-    master_mutex = xbt_os_mutex_init();
-    master_cond = xbt_os_cond_init();
-
-    current_thread_id = xbt_os_thread_self();
-
-#else
+    
+    #ifndef CONTEXT_THREADS
     init_context->exception = xbt_new(ex_ctx_t, 1);
     XBT_CTX_INITIALIZE(init_context->exception);
     __xbt_ex_ctx = _context_ex_ctx;
     init_context->exception = xbt_new(ex_ctx_t, 1);
     XBT_CTX_INITIALIZE(init_context->exception);
     __xbt_ex_ctx = _context_ex_ctx;
@@ -117,12 +114,7 @@ void xbt_context_exit(void)
     }
   }
 
     }
   }
 
-#ifdef CONTEXT_THREADS
-  xbt_os_mutex_destroy(creation_mutex);
-  xbt_os_cond_destroy(creation_cond);
-  xbt_os_mutex_destroy(master_mutex);
-  xbt_os_cond_destroy(master_cond);
-#else
+#ifndef CONTEXT_THREADS
   free(init_context->exception);
 #endif
 
   free(init_context->exception);
 #endif
 
@@ -135,6 +127,7 @@ void xbt_context_exit(void)
 
 }
 
 
 }
 
+
 /*******************************/
 /* Object creation/destruction */
 /*******************************/
 /*******************************/
 /* Object creation/destruction */
 /*******************************/
@@ -166,8 +159,12 @@ xbt_context_new(const char *name,
   res->name = xbt_strdup(name);
 
 #ifdef CONTEXT_THREADS
   res->name = xbt_strdup(name);
 
 #ifdef CONTEXT_THREADS
-  res->mutex = xbt_os_mutex_init();
-  res->cond = xbt_os_cond_init();
+  /* 
+   * initialize the semaphores used to schedule/unschedule 
+   * the process associated to the newly created context 
+   */
+  res->begin = xbt_os_sem_init(0,0);
+  res->end = xbt_os_sem_init(0,0);
 #else
 
   xbt_assert2(getcontext(&(res->uc)) == 0,
 #else
 
   xbt_assert2(getcontext(&(res->uc)) == 0,
@@ -219,6 +216,7 @@ xbt_context_new(const char *name,
  *   (same than first case afterward)
  */
 
  *   (same than first case afterward)
  */
 
+
 /* Argument must be stopped first -- runs in maestro context */
 static void xbt_context_free(xbt_context_t context)
 {
 /* Argument must be stopped first -- runs in maestro context */
 static void xbt_context_free(xbt_context_t context)
 {
@@ -244,12 +242,13 @@ static void xbt_context_free(xbt_context_t context)
 
   xbt_os_thread_join(context->thread, NULL);
 
 
   xbt_os_thread_join(context->thread, NULL);
 
-  xbt_os_mutex_destroy(context->mutex);
-  xbt_os_cond_destroy(context->cond);
+  /* destroy the semaphore used to schedule/unshedule the process */
+       xbt_os_sem_destroy(context->begin);
+       xbt_os_sem_destroy(context->end);
 
   context->thread = NULL;
 
   context->thread = NULL;
-  context->mutex = NULL;
-  context->cond = NULL;
+  context->begin = NULL;
+  context->end = NULL;
 #else
   if (context->exception)
     free(context->exception);
 #else
   if (context->exception)
     free(context->exception);
@@ -270,27 +269,10 @@ static void *__context_wrapper(void *c)
 
 #ifdef CONTEXT_THREADS
   context = (xbt_context_t) c;
 
 #ifdef CONTEXT_THREADS
   context = (xbt_context_t) c;
-  context->thread = xbt_os_thread_self();
-
-  DEBUG3("**[ctx:%p;self:%p]** Lock creation_mutex %p ****", context,
-         (void *) xbt_os_thread_self(), creation_mutex);
-  xbt_os_mutex_lock(creation_mutex);
-  xbt_os_mutex_lock(context->mutex);
-
-  DEBUG4
-    ("**[ctx:%p;self:%p]** Releasing the creator (creation_cond %p,%p) ****",
-     context, (void *) xbt_os_thread_self(), creation_cond, creation_mutex);
-  xbt_os_cond_signal(creation_cond);
-  xbt_os_mutex_unlock(creation_mutex);
-
-  DEBUG4("**[ctx:%p;self:%p]** Going to Jail on lock %p and cond %p ****",
-         context, (void *) xbt_os_thread_self(), context->mutex,
-         context->cond);
-  xbt_os_cond_wait(context->cond, context->mutex);
+  /*context->thread = xbt_os_thread_self();*/
 
 
-  DEBUG3("**[ctx:%p;self:%p]** Unlocking individual %p ****", context,
-         (void *) xbt_os_thread_self(), context->mutex);
-  xbt_os_mutex_unlock(context->mutex);
+  /* signal its starting to the maestro and wait to start its job*/
+  unschedule(context);
 
 #endif
 
 
 #endif
 
@@ -302,7 +284,6 @@ static void *__context_wrapper(void *c)
   xbt_context_stop((context->code) (context->argc, context->argv));
   return NULL;
 }
   xbt_context_stop((context->code) (context->argc, context->argv));
   return NULL;
 }
-
 /** 
  * \param context the context to start
  * 
 /** 
  * \param context the context to start
  * 
@@ -312,26 +293,11 @@ static void *__context_wrapper(void *c)
 void xbt_context_start(xbt_context_t context)
 {
 #ifdef CONTEXT_THREADS
 void xbt_context_start(xbt_context_t context)
 {
 #ifdef CONTEXT_THREADS
-  /* Launch the thread */
-
-  DEBUG3("**[ctx:%p;self:%p]** Locking creation_mutex %p ****", context,
-         xbt_os_thread_self(), creation_mutex);
-  xbt_os_mutex_lock(creation_mutex);
-
-  DEBUG2("**[ctx:%p;self:%p]** Thread create ****", context,
-         xbt_os_thread_self());
-  context->thread =
-    xbt_os_thread_create(context->name, __context_wrapper, context);
-  DEBUG3("**[ctx:%p;self:%p]** Thread created : %p ****", context,
-         xbt_os_thread_self(), context->thread);
-
-  DEBUG4
-    ("**[ctx:%p;self:%p]** Going to jail on creation_cond/mutex (%p,%p) ****",
-     context, xbt_os_thread_self(), creation_cond, creation_mutex);
-  xbt_os_cond_wait(creation_cond, creation_mutex);
-  DEBUG3("**[ctx:%p;self:%p]** Unlocking creation %p ****", context,
-         xbt_os_thread_self(), creation_mutex);
-  xbt_os_mutex_unlock(creation_mutex);
+  /* create the process and start it */
+  context->thread = xbt_os_thread_create(context->name,__context_wrapper, context);
+       
+  /* wait the starting of the newly created process */
+  xbt_os_sem_wait(context->end);
 #else
   makecontext(&(context->uc), (void (*)(void)) __context_wrapper, 1, context);
 #endif
 #else
   makecontext(&(context->uc), (void (*)(void)) __context_wrapper, 1, context);
 #endif
@@ -354,19 +320,10 @@ static void xbt_context_stop(int retvalue)
   DEBUG0("Yielding");
 
 #ifdef CONTEXT_THREADS
   DEBUG0("Yielding");
 
 #ifdef CONTEXT_THREADS
-  /* a java thread has called this function
-   * - update the current context
-   * - signal the condition of the main thread
-   * - wait on its condition
-   * - restore thr current contex
-   */
-
-  xbt_os_mutex_lock(master_mutex);
-  xbt_os_cond_signal(master_cond);
-  xbt_os_mutex_unlock(master_mutex);
-  xbt_os_thread_exit(NULL);     /* We should provide return value in case other wants it */
-
-
+  /* signal to the maestro that it has finished */
+       xbt_os_sem_post(current_context->end);
+       /* exit*/
+       xbt_os_thread_exit(NULL);       /* We should provide return value in case other wants it */
 #else
   __xbt_context_yield(current_context);
 #endif
 #else
   __xbt_context_yield(current_context);
 #endif
@@ -397,10 +354,6 @@ void xbt_context_empty_trash(void)
 
 static void __xbt_context_yield(xbt_context_t context)
 {
 
 static void __xbt_context_yield(xbt_context_t context)
 {
-#ifdef CONTEXT_THREADS
-  xbt_context_t self;
-#endif
-
   xbt_assert0(current_context, "You have to call context_init() first.");
   xbt_assert0(context, "Invalid argument");
 
   xbt_assert0(current_context, "You have to call context_init() first.");
   xbt_assert0(context, "Invalid argument");
 
@@ -416,48 +369,36 @@ static void __xbt_context_yield(xbt_context_t context)
 
 #ifdef CONTEXT_THREADS
 
 
 #ifdef CONTEXT_THREADS
 
-  self = current_context;
-
-  if (is_main_thread()) {
-    /* the main thread has called this function
-     * - update the current context
-     * - signal the condition of the process to run
-     * - wait on its condition
-     * - restore thr current contex
-     */
-
-    xbt_os_mutex_lock(master_mutex);
-    xbt_os_mutex_lock(context->mutex);
-
-    /* update the current context */
-    current_context = context;
-    xbt_os_cond_signal(context->cond);
-    xbt_os_mutex_unlock(context->mutex);
-
-    xbt_os_cond_wait(master_cond, master_mutex);
-    xbt_os_mutex_unlock(master_mutex);
-    /* retore the current context */
-    current_context = self;
-
-  } else {
-    /* a java thread has called this function
-     * - update the current context
-     * - signal the condition of the main thread
-     * - wait on its condition
-     * - restore thr current contex
-     */
-
-    xbt_os_mutex_lock(master_mutex);
-    xbt_os_mutex_lock(context->mutex);
-    /* update the current context */
-    current_context = context;
-    xbt_os_cond_signal(master_cond);
-    xbt_os_mutex_unlock(master_mutex);
-    xbt_os_cond_wait(context->cond, context->mutex);
-    xbt_os_mutex_unlock(context->mutex);
-    /* retore the current context */
-    current_context = self;
-  }
+  if(current_context != init_context && !context->iwannadie)
+       {/* it's a process and it doesn't wants to die (xbt_context_yield()) */
+               
+               /* save the current context */
+               xbt_context_t self = current_context;
+
+               /* update the current context to this context */
+               current_context = context;
+               
+               /* yield itself */
+               unschedule(context);
+               
+               /* restore the current context to the previously saved context */
+               current_context = self;
+       }
+       else
+       { /* maestro wants to schedule a process or a process wants to die (xbt_context_schedule() or xbt_context_kill())*/
+               
+               /* save the current context */
+               xbt_context_t self = current_context;
+               
+               /* update the current context */
+               current_context = context;
+
+               /* schedule the process associated with this context */
+               schedule(context);
+
+               /* restore the current context to the previously saved context */
+               current_context = self;
+       }
 
 #else /* use SUSv2 contexts */
   VOIRP(current_context);
 
 #else /* use SUSv2 contexts */
   VOIRP(current_context);
@@ -502,10 +443,6 @@ static void __xbt_context_yield(xbt_context_t context)
     xbt_context_stop(1);
 }
 
     xbt_context_stop(1);
 }
 
-
-
-
-
 /** 
  * Calling this function makes the current context yield. The context
  * that scheduled it returns from xbt_context_schedule as if nothing
 /** 
  * Calling this function makes the current context yield. The context
  * that scheduled it returns from xbt_context_schedule as if nothing
@@ -554,19 +491,9 @@ void xbt_context_kill(xbt_context_t context)
 }
 
 /* Java cruft I'm gonna kill in the next cleanup round */
 }
 
 /* Java cruft I'm gonna kill in the next cleanup round */
-void xbt_context_set_jprocess(xbt_context_t context, void *jp)
-{
-}
-void *xbt_context_get_jprocess(xbt_context_t context)
-{
-  return NULL;
-}
-void xbt_context_set_jenv(xbt_context_t context, void *je)
-{
-}
-void *xbt_context_get_jenv(xbt_context_t context)
-{
-  return NULL;
-}
+void  xbt_context_set_jprocess(xbt_context_t context, void *jp){}
+void* xbt_context_get_jprocess(xbt_context_t context){return NULL;}
+void  xbt_context_set_jenv(xbt_context_t context,void* je){}
+void* xbt_context_get_jenv(xbt_context_t context){return NULL;}
 
 /* @} */
 
 /* @} */
index 7c82066..75d378a 100644 (file)
@@ -38,8 +38,8 @@ typedef struct s_xbt_context {
 #else   
 # ifdef CONTEXT_THREADS
        xbt_os_thread_t thread; /* a plain dumb thread (portable to posix or windows) */
 #else   
 # ifdef CONTEXT_THREADS
        xbt_os_thread_t thread; /* a plain dumb thread (portable to posix or windows) */
-       xbt_os_cond_t cond;             /* the condition used to synchronize the process        */
-       xbt_os_mutex_t mutex;           /* the mutex used to synchronize the process            */
+       xbt_os_sem_t begin;             /* this semaphore is used to schedule/unschedule the process */
+       xbt_os_sem_t end;               /* this semaphore is used to schedule/unschedule the process */
 # else
        ucontext_t uc;       /* the thread that execute the code */
        char stack[STACK_SIZE];
 # else
        ucontext_t uc;       /* the thread that execute the code */
        char stack[STACK_SIZE];
@@ -58,9 +58,7 @@ typedef struct s_xbt_context {
        void *startup_arg;
        void_f_pvoid_t cleanup_func;
        void *cleanup_arg;
        void *startup_arg;
        void_f_pvoid_t cleanup_func;
        void *cleanup_arg;
-
        int iwannadie;                  /* Set to true by the context when it wants to commit suicide */
        int iwannadie;                  /* Set to true by the context when it wants to commit suicide */
-
 } s_xbt_context_t;
 
 
 } s_xbt_context_t;
 
 
index 4a793e4..0405622 100644 (file)
@@ -23,7 +23,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync_os,xbt,"Synchronization mechanism (OS-l
 /* ********************************* PTHREAD IMPLEMENTATION ************************************ */
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
 /* ********************************* PTHREAD IMPLEMENTATION ************************************ */
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
-
+#include <semaphore.h>
 
 typedef struct xbt_os_thread_ {
    pthread_t t;
 
 typedef struct xbt_os_thread_ {
    pthread_t t;
@@ -93,7 +93,8 @@ static void * wrapper_start_routine(void *s) {
   if ((errcode=pthread_setspecific(xbt_self_thread_key,t)))
     THROW0(system_error,errcode,
           "pthread_setspecific failed for xbt_self_thread_key");   
   if ((errcode=pthread_setspecific(xbt_self_thread_key,t)))
     THROW0(system_error,errcode,
           "pthread_setspecific failed for xbt_self_thread_key");   
-  return (*t->start_routine)(t->param);
+   
+  return (*(t->start_routine))(t->param);
 }
 xbt_os_thread_t xbt_os_thread_create(const char*name,
                                     pvoid_f_pvoid_t start_routine,
 }
 xbt_os_thread_t xbt_os_thread_create(const char*name,
                                     pvoid_f_pvoid_t start_routine,
@@ -286,6 +287,118 @@ void *xbt_os_thread_getparam(void) {
    return t?t->param:NULL;
 }
 
    return t?t->param:NULL;
 }
 
+typedef struct xbt_os_sem_ {
+   sem_t s;
+   int pshared;
+   unsigned int value;
+   const char* name;
+}s_xbt_os_sem_t ;
+
+xbt_os_sem_t
+xbt_os_sem_init(int pshared, unsigned int value)
+{
+       xbt_os_sem_t res = xbt_new(s_xbt_os_sem_t,1);
+       
+       if(sem_init(&(res->s),pshared,value) < 0)
+               THROW1(system_error,errno,"sem_init() failed: %s",
+           strerror(errno));
+   
+   res->pshared = pshared;
+   res->value = value;
+   
+   return res;
+}
+
+void 
+xbt_os_sem_wait(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_wait() failed: %s",
+           strerror(EINVAL));
+       
+       if(sem_wait(&(sem->s)) < 0)
+               THROW1(system_error,errno,"sem_wait() failed: %s",
+           strerror(errno));            
+}
+
+void xbt_os_sem_timedwait(xbt_os_sem_t sem,const struct timespec* abs_timeout)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_timedwait() failed: %s",
+           strerror(EINVAL));
+       
+       /* only throw an exception if the global variable errno is different than ETIMEDOUT :
+        * (the semaphore could not be locked before the specified timeout expired)
+        */
+       if((sem_timedwait(&(sem->s),abs_timeout) < 0) && (ETIMEDOUT != errno))
+               THROW1(system_error,errno,"sem_wait() failed: %s",
+           strerror(errno));   
+}
+
+void 
+xbt_os_sem_post(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_post() failed: %s",
+           strerror(EINVAL));
+       
+       if(sem_post(&(sem->s)) < 0)
+               THROW1(system_error,errno,"sem_post() failed: %s",
+           strerror(errno));            
+}
+
+void
+xbt_os_sem_close(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_close() failed: %s",
+           strerror(EINVAL));
+           
+       if(sem_close(&(sem->s)) < 0)
+               THROW1(system_error,errno,"sem_close() failed: %s",
+           strerror(errno));
+}
+
+xbt_os_sem_t 
+xbt_os_sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
+{
+       sem_t* ps;
+       xbt_os_sem_t res = xbt_new(s_xbt_os_sem_t,1);
+       
+       if(SEM_FAILED == (ps = sem_open(name,oflag, mode, value)))
+               THROW1(system_error,errno,"sem_open() failed: %s",
+           strerror(errno));
+       
+   res->s = *ps;
+   res->value = value;
+   
+   return res; 
+}
+
+void
+xbt_os_sem_destroy(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_destroy() failed: %s",
+           strerror(EINVAL));
+           
+       if(sem_destroy(&(sem->s)) < 0)
+               THROW1(system_error,errno,"sem_destroy() failed: %s",
+           strerror(errno));
+}
+
+void
+xbt_os_sem_get_value(xbt_os_sem_t sem, int* svalue)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_getvalue() failed: %s",
+           strerror(EINVAL));
+           
+       if(sem_getvalue(&(sem->s),svalue) < 0)
+               THROW1(system_error,errno,"sem_getvalue() failed: %s",
+           strerror(errno));
+}
+
 /* ********************************* WINDOWS IMPLEMENTATION ************************************ */
 
 #elif defined(WIN32)
 /* ********************************* WINDOWS IMPLEMENTATION ************************************ */
 
 #elif defined(WIN32)
@@ -298,6 +411,14 @@ typedef struct xbt_os_thread_ {
   void* param;
 } s_xbt_os_thread_t ;
 
   void* param;
 } s_xbt_os_thread_t ;
 
+/* so we can specify the size of the stack of the threads */
+#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
+#endif
+
+/* the default size of the stack of the threads (in bytes)*/
+#define XBT_DEFAULT_THREAD_STACK_SIZE  4096
+
 /* key to the TLS containing the xbt_os_thread_t structure */
 static unsigned long xbt_self_thread_key;
 
 /* key to the TLS containing the xbt_os_thread_t structure */
 static unsigned long xbt_self_thread_key;
 
@@ -312,11 +433,14 @@ void xbt_os_thread_mod_exit(void) {
 
 static DWORD WINAPI  wrapper_start_routine(void *s) {
   xbt_os_thread_t t = (xbt_os_thread_t)s;
 
 static DWORD WINAPI  wrapper_start_routine(void *s) {
   xbt_os_thread_t t = (xbt_os_thread_t)s;
+  void* rv;
  
     if(!TlsSetValue(xbt_self_thread_key,t))
      THROW0(system_error,(int)GetLastError(),"TlsSetValue of data describing the created thread failed");
    
  
     if(!TlsSetValue(xbt_self_thread_key,t))
      THROW0(system_error,(int)GetLastError(),"TlsSetValue of data describing the created thread failed");
    
-   return (DWORD)t->start_routine(t->param);
+   rv = (*(t->start_routine))(t->param);
+
+   return *((DWORD*)rv);
 }
 
 
 }
 
 
@@ -329,9 +453,9 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,pvoid_f_pvoid_t start_rout
    t->start_routine = start_routine ;
    t->param = param;
    
    t->start_routine = start_routine ;
    t->param = param;
    
-   t->handle = CreateThread(NULL,0,
+   t->handle = CreateThread(NULL,XBT_DEFAULT_THREAD_STACK_SIZE,
                            (LPTHREAD_START_ROUTINE)wrapper_start_routine,
                            (LPTHREAD_START_ROUTINE)wrapper_start_routine,
-                           t,0,&(t->id));
+                           t,STACK_SIZE_PARAM_IS_A_RESERVATION,&(t->id));
        
    if(!t->handle) {
      xbt_free(t);
        
    if(!t->handle) {
      xbt_free(t);
@@ -514,7 +638,56 @@ void xbt_os_cond_wait(xbt_os_cond_t cond, xbt_os_mutex_t mutex) {
    EnterCriticalSection (& mutex->lock);
 }
 void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex, double delay) {
    EnterCriticalSection (& mutex->lock);
 }
 void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex, double delay) {
-   THROW_UNIMPLEMENTED;
+   
+        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,%ul)",&(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) {
 }
 
 void xbt_os_cond_signal(xbt_os_cond_t cond) {
@@ -561,4 +734,152 @@ void xbt_os_cond_destroy(xbt_os_cond_t cond){
      THROW0(system_error,0,"Error while destroying the condition");
 }
 
      THROW0(system_error,0,"Error while destroying the condition");
 }
 
+typedef struct xbt_os_sem_ {
+   HANDLE h;
+   unsigned int value;
+   const char* name;
+   CRITICAL_SECTION value_lock;  /* protect access to value of the semaphore  */
+}s_xbt_os_sem_t ;
+
+xbt_os_sem_t
+xbt_os_sem_init(int pshared, unsigned int value)
+{
+       xbt_os_sem_t res;
+       
+       if(0 != pshared)
+       THROW1(arg_error,EPERM,"xbt_os_sem_init() failed: %s",
+           strerror(EPERM));
+           
+       if(value > INT_MAX)
+       THROW1(arg_error,EINVAL,"xbt_os_sem_init() failed: %s",
+           strerror(EINVAL));
+       
+       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_wait(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_wait() failed: %s",
+           strerror(EINVAL));  
+
+       /* 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_timedwait(xbt_os_sem_t sem,const struct timespec* abs_timeout)
+{
+       long timeout;
+       struct timeval tv;
+       
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_timedwait() failed: %s",
+           strerror(EINVAL));  
+           
+       if(!abs_timeout)
+               timeout = INFINITE;
+       else
+       {
+               if(gettimeofday(&tv, NULL) < 0) 
+                       THROW1(system_error,errno,"gettimeofday() failed: %s",
+               strerror(errno));       
+                       
+                timeout = ((long) (abs_timeout->tv_sec - tv.tv_sec) * 1e3 + (long)((abs_timeout->tv_nsec / 1e3) - tv.tv_usec) / 1e3);          
+       }
+       
+       switch(WaitForSingleObject(sem->h,timeout))
+       {
+               case WAIT_OBJECT_0:
+               EnterCriticalSection(&(sem->value_lock));
+               sem->value--;
+               LeaveCriticalSection(&(sem->value_lock));
+               return;
+               
+               case WAIT_TIMEOUT:
+               /* it's not an exception : 
+                * (semaphore could not be locked before the specified timeout expired)
+                */
+               return;
+               
+               default:
+                       
+               THROW1(system_error,GetLastError(),"WaitForSingleObject() failed: %s",
+               strerror(GetLastError()));
+       }
+}
+
+void 
+xbt_os_sem_post(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_post() failed: %s",
+           strerror(EINVAL));
+       
+       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));
+}
+
+xbt_os_sem_t 
+xbt_os_sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
+{
+       THROW_UNIMPLEMENTED;
+}
+
+void
+xbt_os_sem_close(xbt_os_sem_t sem)
+{
+       THROW_UNIMPLEMENTED;
+}
+
+void
+xbt_os_sem_destroy(xbt_os_sem_t sem)
+{
+       if(!sem)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_destroy() failed: %s",
+           strerror(EINVAL));
+       
+       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)
+               THROW1(arg_error,EINVAL,"xbt_os_sem_get_value() failed: %s",
+           strerror(EINVAL));
+       
+       EnterCriticalSection(&(sem->value_lock));  
+       *svalue = sem->value;
+       LeaveCriticalSection(&(sem->value_lock));
+}
+
 #endif
 #endif