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
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)
# 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
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;
*/
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)
*/
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;
- else
+#else
+ return xbt_os_thread_get_specific(smx_current_context_key);
+#endif
+ }
+ else {
return smx_current_context_serial;
+ }
}
/**
*/
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;
- else
+#else
+ xbt_os_thread_set_specific(smx_current_context_key, context);
+#endif
+ }
+ else {
smx_current_context_serial = context;
+ }
}
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
/* 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@
--- /dev/null
+/* 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;
+}