Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Revert "thread_local is C++11, remove the portability layer"
authorMartin Quinson <martin.quinson@loria.fr>
Wed, 9 Mar 2016 00:43:04 +0000 (01:43 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Wed, 9 Mar 2016 00:45:09 +0000 (01:45 +0100)
This reverts commit 3893493151bcdbed55ef359cdfea4563ee8cddb8.

It fails on some platforms (clang 6, gcc 4.7.3), as if that part of
C++11 were not well implemented yet. In a few years maybe.

CMakeLists.txt
include/xbt/base.h
src/simix/smx_context.cpp
tools/cmake/DefinePackages.cmake
tools/cmake/src/internal_config.h.in
tools/cmake/test_prog/prog_thread_storage.c [new file with mode: 0644]

index 7a21113..b0a6d3c 100644 (file)
@@ -307,6 +307,19 @@ if(MINGW)
   set(HAVE_VASPRINTF 1)
 endif()
 
   set(HAVE_VASPRINTF 1)
 endif()
 
+
+#Check if __thread is defined
+execute_process(
+  COMMAND "${CMAKE_C_COMPILER} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_thread_storage.c -o testprog"
+  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+  RESULT_VARIABLE HAVE_thread_storage_run)
+file(REMOVE testprog)
+if(HAVE_thread_storage_run)
+  set(HAVE_THREAD_LOCAL_STORAGE 1)
+else()
+  set(HAVE_THREAD_LOCAL_STORAGE 0)
+endif()
+
 # Our usage of mmap is Linux-specific (flag MAP_ANONYMOUS), but kFreeBSD uses a GNU libc
 IF(HAVE_MMAP AND
    NOT "${CMAKE_SYSTEM}" MATCHES "Linux" AND 
 # Our usage of mmap is Linux-specific (flag MAP_ANONYMOUS), but kFreeBSD uses a GNU libc
 IF(HAVE_MMAP AND
    NOT "${CMAKE_SYSTEM}" MATCHES "Linux" AND 
@@ -317,7 +330,7 @@ IF(HAVE_MMAP AND
   message(STATUS "Warning: MMAP is thought as non functional on this architecture (${CMAKE_SYSTEM})")
 ENDIF()
 
   message(STATUS "Warning: MMAP is thought as non functional on this architecture (${CMAKE_SYSTEM})")
 ENDIF()
 
-if(HAVE_MMAP)
+if(HAVE_MMAP AND HAVE_THREAD_LOCAL_STORAGE)
   SET(HAVE_MMALLOC 1)
 else()
   SET(HAVE_MMALLOC 0)
   SET(HAVE_MMALLOC 1)
 else()
   SET(HAVE_MMALLOC 0)
index a1b6319..bada2f8 100644 (file)
 #   define XBT_ALWAYS_INLINE inline
 #endif
 
 #   define XBT_ALWAYS_INLINE inline
 #endif
 
+#if defined(__GNUC__)
+#   define XBT_THREAD_LOCAL __thread
+#else
+#   define XBT_THREAD_LOCAL No thread local on this architecture
+#endif
+
 /* improvable on gcc (by evaluating arguments only once), but wouldn't be portable */
 #ifdef MIN
 # undef MIN
 /* improvable on gcc (by evaluating arguments only once), but wouldn't be portable */
 #ifdef MIN
 # undef MIN
index f1caa05..82a78fd 100644 (file)
@@ -40,7 +40,11 @@ int smx_context_stack_size;
 int smx_context_stack_size_was_set = 0;
 int smx_context_guard_size;
 int smx_context_guard_size_was_set = 0;
 int smx_context_stack_size_was_set = 0;
 int smx_context_guard_size;
 int smx_context_guard_size_was_set = 0;
-static thread_local smx_context_t smx_current_context_parallel;
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+static XBT_THREAD_LOCAL smx_context_t smx_current_context_parallel;
+#else
+static xbt_os_thread_key_t smx_current_context_key = 0;
+#endif
 static smx_context_t smx_current_context_serial;
 static int smx_parallel_contexts = 1;
 static int smx_parallel_threshold = 2;
 static smx_context_t smx_current_context_serial;
 static int smx_parallel_contexts = 1;
 static int smx_parallel_threshold = 2;
@@ -51,6 +55,11 @@ static e_xbt_parmap_mode_t smx_parallel_synchronization_mode = XBT_PARMAP_DEFAUL
  */
 void SIMIX_context_mod_init(void)
 {
  */
 void SIMIX_context_mod_init(void)
 {
+#if defined(HAVE_THREAD_CONTEXTS) && !defined(HAVE_THREAD_LOCAL_STORAGE)
+  /* the __thread storage class is not available on this platform:
+   * use getspecific/setspecific instead to store the current context in each thread */
+  xbt_os_thread_key_create(&smx_current_context_key);
+#endif
   if (!simix_global->context_factory) {
     /* select the context factory to use to create the contexts */
     if (simgrid::simix::factory_initializer)
   if (!simix_global->context_factory) {
     /* select the context factory to use to create the contexts */
     if (simgrid::simix::factory_initializer)
@@ -272,10 +281,16 @@ void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode) {
  */
 smx_context_t SIMIX_context_get_current(void)
 {
  */
 smx_context_t SIMIX_context_get_current(void)
 {
-  if (SIMIX_context_is_parallel())
+  if (SIMIX_context_is_parallel()) {
+#ifdef HAVE_THREAD_LOCAL_STORAGE
     return smx_current_context_parallel;
     return smx_current_context_parallel;
-  else
+#else
+    return xbt_os_thread_get_specific(smx_current_context_key);
+#endif
+  }
+  else {
     return smx_current_context_serial;
     return smx_current_context_serial;
+  }
 }
 
 /**
 }
 
 /**
@@ -284,8 +299,14 @@ smx_context_t SIMIX_context_get_current(void)
  */
 void SIMIX_context_set_current(smx_context_t context)
 {
  */
 void SIMIX_context_set_current(smx_context_t context)
 {
-  if (SIMIX_context_is_parallel())
+  if (SIMIX_context_is_parallel()) {
+#ifdef HAVE_THREAD_LOCAL_STORAGE
     smx_current_context_parallel = context;
     smx_current_context_parallel = context;
-  else
+#else
+    xbt_os_thread_set_specific(smx_current_context_key, context);
+#endif
+  }
+  else {
     smx_current_context_serial = context;
     smx_current_context_serial = context;
+  }
 }
 }
index 9a56744..abbd3b1 100644 (file)
@@ -1114,6 +1114,7 @@ set(CMAKE_SOURCE_FILES
   tools/cmake/test_prog/prog_snprintf.c
   tools/cmake/test_prog/prog_stackgrowth.c
   tools/cmake/test_prog/prog_stacksetup.c
   tools/cmake/test_prog/prog_snprintf.c
   tools/cmake/test_prog/prog_stackgrowth.c
   tools/cmake/test_prog/prog_stacksetup.c
+  tools/cmake/test_prog/prog_thread_storage.c
   tools/cmake/test_prog/prog_vsnprintf.c
   tools/cmake/cross-mingw.cmake
   tools/stack-cleaner/as
   tools/cmake/test_prog/prog_vsnprintf.c
   tools/cmake/cross-mingw.cmake
   tools/stack-cleaner/as
index 49dfc3e..e64a921 100644 (file)
@@ -30,6 +30,7 @@
 /* Variables for the thread contexts (and parallel mode of raw contexts) */
 #cmakedefine HAVE_PTHREAD              @HAVE_PTHREAD@ /* Define to 1 if threads are usable . */
 #cmakedefine HAVE_PTHREAD_SETAFFINITY  @HAVE_PTHREAD_SETAFFINITY@ /* Does not seems defined on Mac nor Windows */
 /* Variables for the thread contexts (and parallel mode of raw contexts) */
 #cmakedefine HAVE_PTHREAD              @HAVE_PTHREAD@ /* Define to 1 if threads are usable . */
 #cmakedefine HAVE_PTHREAD_SETAFFINITY  @HAVE_PTHREAD_SETAFFINITY@ /* Does not seems defined on Mac nor Windows */
+#cmakedefine HAVE_THREAD_LOCAL_STORAGE @HAVE_THREAD_LOCAL_STORAGE@ /* If __thread is available */
 
 /* Variables for the raw contexts (to select the right assembly code) */
 #cmakedefine PROCESSOR_i686         @PROCESSOR_i686@
 
 /* Variables for the raw contexts (to select the right assembly code) */
 #cmakedefine PROCESSOR_i686         @PROCESSOR_i686@
diff --git a/tools/cmake/test_prog/prog_thread_storage.c b/tools/cmake/test_prog/prog_thread_storage.c
new file mode 100644 (file)
index 0000000..edcab03
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (c) 2010-2011, 2013-2014. 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 <stdio.h>
+
+#ifdef _MSC_VER
+__declspec(thread)
+#else 
+__thread 
+#endif
+int thread_specific_variable = 0;
+
+int main(void) {
+
+  thread_specific_variable++;
+  printf("%d\n", thread_specific_variable);
+  return 0;
+}