Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
oups! forgot to rest some parts ...
[simgrid.git] / src / xbt / xbt_os_thread.c
index 7d58f3e..05924d2 100644 (file)
@@ -8,7 +8,7 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include "gras_config.h"
+#include "internal_config.h"
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
 #include "xbt/ex_interface.h"   /* We play crude games with exceptions */
@@ -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
@@ -54,6 +53,11 @@ static xbt_os_thread_t main_thread = NULL;
 static pthread_key_t xbt_self_thread_key;
 static int thread_mod_inited = 0;
 
+/* attribute structure to handle pthread stack size changing */
+//FIXME: find where to put this
+static pthread_attr_t attr;
+static int thread_attr_inited = 0;
+
 /* frees the xbt_os_thread_t corresponding to the current thread */
 static void xbt_os_thread_free_thread_data(xbt_os_thread_t thread)
 {
@@ -75,8 +79,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 */
 }
 
@@ -135,10 +138,15 @@ void xbt_os_thread_mod_postexit(void)
   __xbt_ex_terminate = &__xbt_ex_terminate_default;
 }
 
+/* this function is critical to tesh+mmalloc, don't mess with it */
 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,12 +158,13 @@ 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;
 }
 
+
 xbt_os_thread_t xbt_os_thread_create(const char *name,
                                      pvoid_f_pvoid_t start_routine,
                                      void *param,
@@ -172,14 +181,33 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,
   XBT_RUNNING_CTX_INITIALIZE(res_thread->running_ctx);
   res_thread->extra_data = extra_data;
   
-  if ((errcode = pthread_create(&(res_thread->t), NULL,
+  if ((errcode = pthread_create(&(res_thread->t), thread_attr_inited!=0? &attr: NULL,
                                 wrapper_start_routine, res_thread)))
     THROWF(system_error, errcode,
            "pthread_create failed: %s", strerror(errcode));
 
+
+
   return res_thread;
 }
 
+
+void xbt_os_thread_setstacksize(int stack_size)
+{
+  size_t def=0;
+  if(stack_size<0)xbt_die("stack size is negative, maybe it exceeds MAX_INT?\n");
+  pthread_attr_init(&attr);
+  pthread_attr_getstacksize (&attr, &def);
+  int res = pthread_attr_setstacksize (&attr, stack_size);
+  if ( res!=0 ) {
+    if(res==EINVAL)XBT_WARN("Thread stack size is either < PTHREAD_STACK_MIN, > the max limit of the system, or perhaps not a multiple of PTHREAD_STACK_MIN - The parameter was ignored");
+    else XBT_WARN("unknown error in pthread stacksize setting");
+
+    pthread_attr_setstacksize (&attr, def);
+  }
+  thread_attr_inited=1;
+}
+
 const char *xbt_os_thread_name(xbt_os_thread_t t)
 {
   return t->name;
@@ -496,7 +524,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));
@@ -639,8 +667,8 @@ 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
+static int stack_size=0;
 /* key to the TLS containing the xbt_os_thread_t structure */
 static unsigned long xbt_self_thread_key;
 
@@ -691,7 +719,7 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,
   t->start_routine = start_routine;
   t->param = param;
   t->extra_data = extra_data;
-  t->handle = CreateThread(NULL, XBT_DEFAULT_THREAD_STACK_SIZE,
+  t->handle = CreateThread(NULL, stack_size==0 ? XBT_DEFAULT_THREAD_STACK_SIZE : stack_size,
                            (LPTHREAD_START_ROUTINE) wrapper_start_routine,
                            t, STACK_SIZE_PARAM_IS_A_RESERVATION, &(t->id));
 
@@ -703,6 +731,11 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,
   return t;
 }
 
+void xbt_os_thread_setstacksize(int size)
+{
+  stack_size = size;
+}
+
 const char *xbt_os_thread_name(xbt_os_thread_t t)
 {
   return t->name;
@@ -730,8 +763,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);
 }
@@ -1161,6 +1193,33 @@ 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;
@@ -1180,7 +1239,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;