Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : move functions about snapshot comparison in a separate file mc_compare.c
[simgrid.git] / src / xbt / xbt_os_thread.c
index c79377a..e18ae2e 100644 (file)
@@ -23,7 +23,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync_os, xbt,
 /* ********************************* PTHREAD IMPLEMENTATION ************************************ */
 #ifdef HAVE_PTHREAD_H
 
-#include <pthread.h>
 #include <semaphore.h>
 
 #ifdef HAVE_MUTEX_TIMEDLOCK
@@ -75,8 +74,7 @@ static xbt_running_ctx_t *_os_thread_get_running_ctx(void)
 static void _os_thread_ex_terminate(xbt_ex_t * e)
 {
   xbt_ex_display(e);
-
-  abort();
+  xbt_abort();
   /* FIXME: there should be a configuration variable to choose to kill everyone or only this one */
 }
 
@@ -138,7 +136,11 @@ void xbt_os_thread_mod_postexit(void)
 int xbt_os_thread_atfork(void (*prepare)(void),
                          void (*parent)(void), void (*child)(void))
 {
+#ifdef WIN32
+  THROW_UNIMPLEMENTED; //pthread_atfork is not implemented in pthread.h on windows
+#else
   return pthread_atfork(prepare, parent, child);
+#endif
 }
 
 static void *wrapper_start_routine(void *s)
@@ -150,7 +152,7 @@ static void *wrapper_start_routine(void *s)
     THROWF(system_error, errcode,
            "pthread_setspecific failed for xbt_self_thread_key");
 
-  void *res = (*(t->start_routine)) (t->param);
+  void *res = t->start_routine(t->param);
   if (t->detached)
     xbt_os_thread_free_thread_data(t);
   return res;
@@ -219,6 +221,24 @@ xbt_os_thread_t xbt_os_thread_self(void)
   return res;
 }
 
+void xbt_os_thread_key_create(xbt_os_thread_key_t* key) {
+
+  int errcode;
+  if ((errcode = pthread_key_create(key, NULL)))
+    THROWF(system_error, errcode, "pthread_key_create failed");
+}
+
+void xbt_os_thread_set_specific(xbt_os_thread_key_t key, void* value) {
+
+  int errcode;
+  if ((errcode = pthread_setspecific(key, value)))
+    THROWF(system_error, errcode, "pthread_setspecific failed");
+}
+
+void* xbt_os_thread_get_specific(xbt_os_thread_key_t key) {
+  return pthread_getspecific(key);
+}
+
 void xbt_os_thread_detach(xbt_os_thread_t thread)
 {
   thread->detached = 1;
@@ -242,12 +262,6 @@ typedef struct xbt_os_mutex_ {
   pthread_mutex_t m;
 } s_xbt_os_mutex_t;
 
-typedef struct xbt_os_rmutex_ {
-  xbt_os_mutex_t mutex;
-  xbt_os_thread_t owner;
-  int count;
-} s_xbt_os_rmutex_t;
-
 #include <time.h>
 #include <math.h>
 
@@ -484,7 +498,7 @@ xbt_os_sem_t xbt_os_sem_init(unsigned int value)
   if ((res->ps == (sem_t *) SEM_FAILED) && (errno == ENAMETOOLONG)) {
     /* Old darwins only allow 13 chars. Did you create *that* amount of semaphores? */
     res->name[13] = '\0';
-    res->ps = sem_open(res->name, O_CREAT, 0644, 1);
+    res->ps = sem_open(res->name, O_CREAT, 0644, value);
   }
   if ((res->ps == (sem_t *) SEM_FAILED))
     THROWF(system_error, errno, "sem_open() failed: %s", strerror(errno));
@@ -627,7 +641,7 @@ typedef struct xbt_os_thread_ {
 #endif
 
 /* the default size of the stack of the threads (in bytes)*/
-#define XBT_DEFAULT_THREAD_STACK_SIZE  4096
+#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;
@@ -718,8 +732,7 @@ void xbt_os_thread_join(xbt_os_thread_t thread, void **thread_return)
 
   CloseHandle(thread->handle);
 
-  if (thread->name)
-    free(thread->name);
+  free(thread->name);
 
   free(thread);
 }
@@ -732,6 +745,21 @@ void xbt_os_thread_exit(int *retval)
     ExitThread(0);
 }
 
+void xbt_os_thread_key_create(xbt_os_thread_key_t* key) {
+
+  *key = TlsAlloc();
+}
+
+void xbt_os_thread_set_specific(xbt_os_thread_key_t key, void* value) {
+
+  if (!TlsSetValue(key, value))
+    THROWF(system_error, (int) GetLastError(), "TlsSetValue() failed");
+}
+
+void* xbt_os_thread_get_specific(xbt_os_thread_key_t key) {
+  return TlsGetValue(key);
+}
+
 void xbt_os_thread_detach(xbt_os_thread_t thread)
 {
   THROW_UNIMPLEMENTED;
@@ -1134,6 +1162,40 @@ void xbt_os_sem_get_value(xbt_os_sem_t sem, int *svalue)
 
 #endif
 
+
+/** @brief Returns the amount of cores on the current host */
+int xbt_os_get_numcores(void) {
+#ifdef WIN32
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+    return sysinfo.dwNumberOfProcessors;
+#elif MACOS
+    int nm[2];
+    size_t len = 4;
+    uint32_t count;
+
+    nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
+    sysctl(nm, 2, &count, &len, NULL, 0);
+
+    if(count < 1) {
+        nm[1] = HW_NCPU;
+        sysctl(nm, 2, &count, &len, NULL, 0);
+        if(count < 1) { count = 1; }
+    }
+    return count;
+#else
+    return sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+}
+
+
+/***** reentrant mutexes *****/
+typedef struct xbt_os_rmutex_ {
+  xbt_os_mutex_t mutex;
+  xbt_os_thread_t owner;
+  int count;
+} s_xbt_os_rmutex_t;
+
 void xbt_os_thread_set_extra_data(void *data)
 {
   xbt_os_thread_self()->extra_data = data;
@@ -1146,7 +1208,7 @@ void *xbt_os_thread_get_extra_data(void)
 
 xbt_os_rmutex_t xbt_os_rmutex_init(void)
 {
-  xbt_os_rmutex_t rmutex = xbt_new0(struct xbt_os_rmutex_, 0);
+  xbt_os_rmutex_t rmutex = xbt_new0(struct xbt_os_rmutex_, 1);
   rmutex->mutex = xbt_os_mutex_init();
   rmutex->owner = NULL;
   rmutex->count = 0;
@@ -1156,7 +1218,12 @@ xbt_os_rmutex_t xbt_os_rmutex_init(void)
 void xbt_os_rmutex_acquire(xbt_os_rmutex_t rmutex)
 {
   xbt_os_thread_t self = xbt_os_thread_self();
-  xbt_assert(self != NULL, "Cannot get my own thread object (is the thread module initialized?)");
+
+  if (self == NULL) {
+    /* the thread module is not initialized yet */
+    rmutex->owner = NULL;
+    return;
+  }
 
   if (self != rmutex->owner) {
     xbt_os_mutex_acquire(rmutex->mutex);
@@ -1169,6 +1236,11 @@ void xbt_os_rmutex_acquire(xbt_os_rmutex_t rmutex)
 
 void xbt_os_rmutex_release(xbt_os_rmutex_t rmutex)
 {
+  if (rmutex->owner == NULL) {
+    /* the thread module was not initialized */
+    return;
+  }
+
   xbt_assert(rmutex->owner == xbt_os_thread_self());
 
   if (--rmutex->count == 0) {