Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'coverity_scan' of github.com:mquinson/simgrid
[simgrid.git] / src / xbt / xbt_os_thread.c
index c9dd691..78c4733 100644 (file)
@@ -1,38 +1,46 @@
 /* xbt_os_thread -- portability layer over the pthread API                  */
 /* Used in RL to get win/lin portability, and in SG when CONTEXT_THREAD     */
-/* in SG, when using CONTEXT_UCONTEXT, xbt_os_thread_stub is used instead   */
+/* in SG, when using HAVE_UCONTEXT_CONTEXTS, xbt_os_thread_stub is used instead   */
 
-/* Copyright (c) 2007-2014. The SimGrid Team.
+/* Copyright (c) 2007-2015. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* 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 "internal_config.h"
+#if defined(WIN32)
+#elif defined(__MACH__) && defined(__APPLE__)
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "src/internal_config.h"
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
-#include "xbt/ex_interface.h"   /* We play crude games with exceptions */
-#include "portable.h"
+#include "src/xbt/ex_interface.h"   /* We play crude games with exceptions */
+#include "src/portable.h"
 #include "xbt/xbt_os_time.h"    /* Portable time facilities */
 #include "xbt/xbt_os_thread.h"  /* This module */
-#include "xbt_modinter.h"       /* Initialization/finalization of this module */
+#include "src/xbt_modinter.h"       /* Initialization/finalization of this module */
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync_os, xbt,
                                 "Synchronization mechanism (OS-level)");
 
 /* ********************************* PTHREAD IMPLEMENTATION ************************************ */
-#ifdef HAVE_PTHREAD_H
+#ifndef _XBT_WIN32
 
+#include <pthread.h>
 #include <limits.h>
 #include <semaphore.h>
 
-#ifdef HAVE_MUTEX_TIMEDLOCK
-/* redefine the function header since we fail to get this from system headers on amd (at least) */
-int pthread_mutex_timedlock(pthread_mutex_t * mutex,
-                            const struct timespec *abs_timeout);
+#ifdef CORE_BINDING
+#define _GNU_SOURCE
+#include <sched.h>
 #endif
 
-
 /* use named sempahore when sem_init() does not work */
 #ifndef HAVE_SEM_INIT
 static int next_sem_ID = 0;
@@ -95,15 +103,18 @@ void xbt_os_thread_mod_preinit(void)
            "pthread_key_create failed for xbt_self_thread_key");
   
   main_thread = xbt_new(s_xbt_os_thread_t, 1);
+  main_thread->name = NULL;
+  main_thread->detached = 0;
   main_thread->name = (char *) "main";
-  main_thread->start_routine = NULL;
   main_thread->param = NULL;
+  main_thread->start_routine = NULL;
   main_thread->running_ctx = xbt_new(xbt_running_ctx_t, 1);
+  main_thread->extra_data = NULL;
   XBT_RUNNING_CTX_INITIALIZE(main_thread->running_ctx);
 
   if ((errcode = pthread_setspecific(xbt_self_thread_key, main_thread)))
     THROWF(system_error, errcode,
-           "pthread_setspecific failed for xbt_self_thread_key");
+           "Impossible to set the SimGrid identity descriptor to the main thread (pthread_setspecific failed)");
   
   __xbt_running_ctx_fetch = _os_thread_get_running_ctx;
   __xbt_ex_terminate = _os_thread_ex_terminate;
@@ -193,6 +204,18 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,
 }
 
 
+#ifdef CORE_BINDING
+int xbt_os_thread_bind(xbt_os_thread_t thread, int cpu){
+  pthread_t pthread = thread->t;
+  int errcode = 0;
+  cpu_set_t cpuset;
+  CPU_ZERO(&cpuset);
+  CPU_SET(cpu, &cpuset);
+  errcode = pthread_setaffinity_np(pthread, sizeof(cpu_set_t), &cpuset);
+  return errcode;
+}
+#endif
+
 void xbt_os_thread_setstacksize(int stack_size)
 {
   size_t alignment[] = {
@@ -271,14 +294,10 @@ void xbt_os_thread_exit(int *retval)
 
 xbt_os_thread_t xbt_os_thread_self(void)
 {
-  xbt_os_thread_t res;
-
   if (!thread_mod_inited)
     return NULL;
 
-  res = pthread_getspecific(xbt_self_thread_key);
-
-  return res;
+  return pthread_getspecific(xbt_self_thread_key);
 }
 
 void xbt_os_thread_key_create(xbt_os_thread_key_t* key) {
@@ -560,7 +579,7 @@ xbt_os_sem_t xbt_os_sem_init(unsigned int value)
     res->name[13] = '\0';
     res->ps = sem_open(res->name, O_CREAT, 0644, value);
   }
-  if ((res->ps == (sem_t *) SEM_FAILED))
+  if (res->ps == (sem_t *) SEM_FAILED)
     THROWF(system_error, errno, "sem_open() failed: %s", strerror(errno));
 
   /* Remove the name from the semaphore namespace: we never join on it */
@@ -709,6 +728,16 @@ static unsigned long xbt_self_thread_key;
 void xbt_os_thread_mod_preinit(void)
 {
   xbt_self_thread_key = TlsAlloc();
+
+  xbt_os_thread_t main_thread = xbt_new0(s_xbt_os_thread_t, 1);
+  main_thread->name = (char *) "main";
+  main_thread->start_routine = NULL;
+  main_thread->param = NULL;
+
+  if (!TlsSetValue(xbt_self_thread_key, main_thread))
+    THROWF(system_error, (int)GetLastError(),
+           "Impossible to set the SimGrid identity descriptor to the main thread (TlsSetValue() failed)");
+
 }
 
 void xbt_os_thread_mod_postexit(void)
@@ -1239,7 +1268,7 @@ int xbt_os_get_numcores(void) {
     SYSTEM_INFO sysinfo;
     GetSystemInfo(&sysinfo);
     return sysinfo.dwNumberOfProcessors;
-#elif MACOS
+#elif defined(__APPLE__) && defined(__MACH__)
     int nm[2];
     size_t len = 4;
     uint32_t count;
@@ -1273,8 +1302,11 @@ void xbt_os_thread_set_extra_data(void *data)
 
 void *xbt_os_thread_get_extra_data(void)
 {
-  xbt_os_thread_t self = xbt_os_thread_self();
-  return self? self->extra_data : NULL;
+  xbt_os_thread_t thread = xbt_os_thread_self();
+  if (thread)
+    return xbt_os_thread_self()->extra_data;
+  else
+    return NULL;
 }
 
 xbt_os_rmutex_t xbt_os_rmutex_init(void)