X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/3cdd0ac83adfa4f28b05b4c1961555e5203bc6a8..41c54c2772412935a5c8fc9f2d09e623c0383ae7:/src/xbt/xbt_os_thread.c diff --git a/src/xbt/xbt_os_thread.c b/src/xbt/xbt_os_thread.c index 2e9e91f910..78c47333eb 100644 --- a/src/xbt/xbt_os_thread.c +++ b/src/xbt/xbt_os_thread.c @@ -1,37 +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, 2008, 2009, 2010. 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 "gras_config.h" +#if defined(WIN32) +#elif defined(__MACH__) && defined(__APPLE__) +#include +#include +#include +#else +#include +#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 +#include #include -#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 #endif - /* use named sempahore when sem_init() does not work */ #ifndef HAVE_SEM_INIT static int next_sem_ID = 0; @@ -53,10 +62,9 @@ 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 */ +/* defaults attribute for pthreads */ //FIXME: find where to put this -static pthread_attr_t attr; -static int thread_attr_inited = 0; +static pthread_attr_t thread_attr; /* frees the xbt_os_thread_t corresponding to the current thread */ static void xbt_os_thread_free_thread_data(xbt_os_thread_t thread) @@ -95,20 +103,24 @@ 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; + pthread_attr_init(&thread_attr); + thread_mod_inited = 1; #ifndef HAVE_SEM_INIT @@ -181,7 +193,7 @@ 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), thread_attr_inited!=0? &attr: NULL, + if ((errcode = pthread_create(&(res_thread->t), &thread_attr, wrapper_start_routine, res_thread))) THROWF(system_error, errcode, "pthread_create failed: %s", strerror(errcode)); @@ -192,11 +204,65 @@ 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) { - pthread_attr_init(&attr); - pthread_attr_setstacksize (&attr, stack_size); - thread_attr_inited=1; + size_t alignment[] = { + xbt_pagesize, +#ifdef PTHREAD_STACK_MIN + PTHREAD_STACK_MIN, +#endif + 0 + }; + size_t sz; + int res; + int i; + + if (stack_size < 0) + xbt_die("stack size %d is negative, maybe it exceeds MAX_INT?", stack_size); + + sz = stack_size; + res = pthread_attr_setstacksize(&thread_attr, sz); + + for (i = 0; res == EINVAL && alignment[i] > 0; i++) { + /* Invalid size, try again with next multiple of alignment[i]. */ + size_t rem = sz % alignment[i]; + if (rem != 0 || sz == 0) { + size_t sz2 = sz - rem + alignment[i]; + XBT_DEBUG("pthread_attr_setstacksize failed for %zd, try again with %zd", + sz, sz2); + sz = sz2; + res = pthread_attr_setstacksize(&thread_attr, sz); + } + } + + if (res == EINVAL) + XBT_WARN("invalid stack size (maybe too big): %zd", sz); + else if (res != 0) + XBT_WARN("unknown error %d in pthread stacksize setting: %zd", res, sz); +} + +void xbt_os_thread_setguardsize(int guard_size) +{ +#ifdef WIN32 + THROW_UNIMPLEMENTED; //pthread_attr_setguardsize is not implemented in pthread.h on windows +#else + size_t sz = guard_size; + int res = pthread_attr_setguardsize(&thread_attr, sz); + if (res) + XBT_WARN("pthread_attr_setguardsize failed (%d) for size: %zd", res, sz); +#endif } const char *xbt_os_thread_name(xbt_os_thread_t t) @@ -228,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) { @@ -321,7 +383,7 @@ void xbt_os_mutex_timedacquire(xbt_os_mutex_t mutex, double delay) THROWF(timeout_error, 0, "mutex %p not ready", mutex); default: THROWF(system_error, errcode, - "xbt_mutex_timedacquire(%p) failed: %s", mutex, + "xbt_os_mutex_timedacquire(%p) failed: %s", mutex, strerror(errcode)); } @@ -517,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 */ @@ -666,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) @@ -722,9 +794,14 @@ xbt_os_thread_t xbt_os_thread_create(const char *name, return t; } -void xbt_os_thread_setstacksize(int stack_size) +void xbt_os_thread_setstacksize(int size) { - stack_size=stack_size; + stack_size = size; +} + +void xbt_os_thread_setguardsize(int size) +{ + XBT_WARN("xbt_os_thread_setguardsize is not implemented (%d)", size); } const char *xbt_os_thread_name(xbt_os_thread_t t) @@ -1191,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; @@ -1225,7 +1302,11 @@ void xbt_os_thread_set_extra_data(void *data) void *xbt_os_thread_get_extra_data(void) { - return xbt_os_thread_self()->extra_data; + 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)