Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot//simgrid/simgrid
authorChristophe Thiéry <christopho128@gmail.com>
Fri, 22 Apr 2011 14:13:14 +0000 (16:13 +0200)
committerChristophe Thiéry <christopho128@gmail.com>
Fri, 22 Apr 2011 14:13:14 +0000 (16:13 +0200)
include/simix/context.h
src/include/xbt/xbt_os_thread.h
src/simix/private.h
src/simix/smx_context.c
src/simix/smx_context_base.c
src/simix/smx_context_raw.c
src/simix/smx_context_sysv.c
src/xbt/xbt_os_thread.c

index 055fa3b..712b07a 100644 (file)
@@ -60,7 +60,11 @@ extern smx_ctx_factory_initializer_t smx_factory_initializer_to_use;
 extern char* smx_context_factory_name;
 extern int smx_context_stack_size;
 
-#ifdef CONTEXT_THREADS
+#if defined(CONTEXT_THREADS) && !defined(APPLE)
+#define HAVE_THREAD_LOCAL_STORAGE 1
+#endif
+
+#ifdef HAVE_THREAD_LOCAL_STORAGE
 extern __thread smx_context_t smx_current_context;
 #else
 extern smx_context_t smx_current_context;
@@ -72,7 +76,7 @@ extern smx_context_t smx_current_context;
 /* the following function pointers types describe the interface that all context
    concepts must implement */
 /* each context type derive from this structure, so they must contain this structure
- * at their begining -- OOP in C :/ */
+ * at their beginning -- OOP in C :/ */
 typedef struct s_smx_context {
   s_xbt_swag_hookup_t hookup;
   xbt_main_func_t code;
index 597815d..22d56bb 100644 (file)
@@ -26,6 +26,8 @@ SG_BEGIN_DECL()
   /** \brief Thread data type (opaque structure) */
 typedef struct xbt_os_thread_ *xbt_os_thread_t;
 
+typedef unsigned int xbt_os_thread_key_t;
+
 /* Calls pthread_atfork() if present, and else does nothing.
  * The only known user of this wrapper is mmalloc_preinit().
  */
@@ -46,6 +48,9 @@ XBT_PUBLIC(const char *) xbt_os_thread_self_name(void);
 XBT_PUBLIC(const char *) xbt_os_thread_name(xbt_os_thread_t);
 XBT_PUBLIC(void) xbt_os_thread_set_extra_data(void *data);
 XBT_PUBLIC(void *) xbt_os_thread_get_extra_data(void);
+XBT_PUBLIC(void) xbt_os_thread_key_create(xbt_os_thread_key_t* key);
+XBT_PUBLIC(void) xbt_os_thread_set_specific(xbt_os_thread_key_t key, void* value);
+XBT_PUBLIC(void*) xbt_os_thread_get_specific(xbt_os_thread_key_t key);
   /* xbt_os_thread_join frees the joined thread (ie the XBT wrapper around it, the OS frees the rest) */
 XBT_PUBLIC(void) xbt_os_thread_join(xbt_os_thread_t thread,
                                     void **thread_return);
index ac56516..cce6355 100644 (file)
@@ -150,11 +150,11 @@ static XBT_INLINE e_smx_state_t SIMIX_action_map_state(e_surf_action_state_t sta
   }
 }
 
-
-
 void SIMIX_context_mod_init(void);
 void SIMIX_context_mod_exit(void);
 
+XBT_INLINE void SIMIX_context_set_current(smx_context_t context);
+XBT_INLINE smx_context_t SIMIX_context_get_current(void);
 
 /* All factories init */
 void SIMIX_ctx_thread_factory_init(smx_context_factory_t *factory);
index 9f2cccb..ba9bb88 100644 (file)
@@ -9,7 +9,8 @@
 #include "portable.h"
 #include "xbt/log.h"
 #include "xbt/swag.h"
-#include "private.h"
+#include "xbt/xbt_os_thread.h"
+#include "src/simix/private.h"
 #include "simix/context.h"
 #include "gras_config.h"
 
@@ -20,10 +21,11 @@ char* smx_context_factory_name = NULL; /* factory name specified by --cfg=contex
 smx_ctx_factory_initializer_t smx_factory_initializer_to_use = NULL;
 int smx_context_stack_size = 128 * 1024;
 
-#ifdef CONTEXT_THREADS
+#ifdef HAVE_THREAD_LOCAL_STORAGE
 __thread smx_context_t smx_current_context;
 #else
-smx_context_t smx_current_context;
+smx_context_t smx_current_context; /* define it anyway, will be used in non-parallel mode */
+static xbt_os_thread_key_t smx_current_context_key = 0;
 #endif
 
 static int smx_parallel_contexts = 1;
@@ -70,6 +72,12 @@ void SIMIX_context_mod_init(void)
       }
     }
   }
+
+#if defined(CONTEXT_THREADS) && !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
 }
 
 /**
@@ -154,3 +162,29 @@ XBT_INLINE int SIMIX_context_get_parallel_threshold(void) {
   return smx_parallel_threshold;
 }
 
+/**
+ * \brief Returns the current context of this thread.
+ * \return the current context of this thread
+ */
+XBT_INLINE smx_context_t SIMIX_context_get_current(void)
+{
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  return smx_current_context;
+#else
+  return xbt_os_thread_get_specific(smx_current_context_key);
+#endif
+}
+
+/**
+ * \brief Sets the current context of this thread.
+ * \param context the context to set
+ */
+XBT_INLINE void SIMIX_context_set_current(smx_context_t context)
+{
+#ifdef HAVE_THREAD_LOCAL_STORAGE
+  smx_current_context = context;
+#else
+  xbt_os_thread_set_specific(smx_current_context_key, context);
+#endif
+}
+
index 7176030..85b24fe 100644 (file)
@@ -10,6 +10,7 @@
 #include "xbt/function_types.h"
 #include "simix/simix.h"
 #include "simix/context.h"
+#include "simix/private.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(bindings);
 
@@ -55,8 +56,8 @@ smx_ctx_base_factory_create_context_sized(size_t size,
     context->argc = argc;
     context->argv = argv;
     context->code = code;
-  }else{
-    smx_current_context = context;
+  } else {
+    SIMIX_context_set_current(context);
   }
   context->data = data;
 
@@ -93,7 +94,7 @@ void smx_ctx_base_stop(smx_context_t context)
 
 smx_context_t smx_ctx_base_self(void)
 {
-  return smx_current_context;
+  return SIMIX_context_get_current();
 }
 
 void *smx_ctx_base_get_data(smx_context_t context)
index 8b797c5..8a9a6f5 100644 (file)
@@ -242,7 +242,7 @@ static void smx_ctx_raw_free(smx_context_t context)
 
 static void smx_ctx_raw_suspend(smx_context_t context)
 {
-  smx_current_context = (smx_context_t)maestro_raw_context;
+  SIMIX_context_set_current((smx_context_t) maestro_raw_context);
   raw_swapcontext(
       &((smx_ctx_raw_t) context)->stack_top,
       ((smx_ctx_raw_t) context)->old_stack_top);
@@ -264,7 +264,7 @@ static void smx_ctx_raw_wrapper(smx_ctx_raw_t context)
 static void smx_ctx_raw_resume(smx_process_t process)
 {
   smx_ctx_raw_t context = (smx_ctx_raw_t)process->context;
-  smx_current_context = (smx_context_t)context;
+  SIMIX_context_set_current((smx_context_t) context);
   raw_swapcontext(
       &((smx_ctx_raw_t) context)->old_stack_top,
       ((smx_ctx_raw_t) context)->stack_top);
@@ -363,7 +363,7 @@ static void smx_ctx_raw_runall_parallel(xbt_dynar_t processes)
 
 static smx_context_t smx_ctx_raw_self_parallel(void)
 {
-  return smx_current_context;
+  return SIMIX_context_get_current();
 }
 
 static int smx_ctx_raw_get_thread_id(){
index 41341b6..24189f8 100644 (file)
@@ -190,7 +190,7 @@ void smx_ctx_sysv_wrapper(int first, ...)
 
 void smx_ctx_sysv_suspend(smx_context_t context)
 {
-  smx_current_context = (smx_context_t)maestro_context;
+  SIMIX_context_set_current((smx_context_t) maestro_context);
   int rv;
   rv = swapcontext(&((smx_ctx_sysv_t) context)->uc, &((smx_ctx_sysv_t)context)->old_uc);
 
@@ -199,7 +199,7 @@ void smx_ctx_sysv_suspend(smx_context_t context)
 
 void smx_ctx_sysv_resume(smx_context_t context)
 {
-  smx_current_context = context; 
+  SIMIX_context_set_current(context);
   int rv;
   rv = swapcontext(&((smx_ctx_sysv_t)context)->old_uc, &((smx_ctx_sysv_t) context)->uc);
 
@@ -221,10 +221,10 @@ void smx_ctx_sysv_runall(xbt_dynar_t processes)
 void smx_ctx_sysv_resume_parallel(smx_process_t process)
 {
   smx_context_t context = process->context;
-  smx_current_context = (smx_context_t)context;
+  SIMIX_context_set_current((smx_context_t) context);
   int rv;
   rv = swapcontext(&((smx_ctx_sysv_t)context)->old_uc, &((smx_ctx_sysv_t) context)->uc);
-  smx_current_context = (smx_context_t)maestro_context;
+  SIMIX_context_set_current((smx_context_t) maestro_context);
 
   xbt_assert((rv == 0), "Context swapping failure");
 }
@@ -241,7 +241,7 @@ smx_context_t smx_ctx_sysv_self_parallel(void)
 {
   /*smx_context_t self_context = (smx_context_t) xbt_os_thread_get_extra_data();
   return self_context ? self_context : (smx_context_t) maestro_context;*/
-  return smx_current_context;
+  return SIMIX_context_get_current();
 }
 
 int smx_ctx_sysv_get_thread_id(void)
index cdafb51..7d58f3e 100644 (file)
@@ -219,6 +219,24 @@ xbt_os_thread_t xbt_os_thread_self(void)
   return res;
 }
 
+void xbt_os_thread_key_create(xbt_os_thread_key_t* key) {
+
+  int errcode;
+  if ((errcode = pthread_key_create(key, NULL)))
+    THROWF(system_error, errcode, "pthread_key_create failed");
+}
+
+void xbt_os_thread_set_specific(xbt_os_thread_key_t key, void* value) {
+
+  int errcode;
+  if ((errcode = pthread_setspecific(key, value)))
+    THROWF(system_error, errcode, "pthread_setspecific failed");
+}
+
+void* xbt_os_thread_get_specific(xbt_os_thread_key_t key) {
+  return pthread_getspecific(key);
+}
+
 void xbt_os_thread_detach(xbt_os_thread_t thread)
 {
   thread->detached = 1;
@@ -726,6 +744,21 @@ void xbt_os_thread_exit(int *retval)
     ExitThread(0);
 }
 
+void xbt_os_thread_key_create(xbt_os_thread_key_t* key) {
+
+  *key = TlsAlloc();
+}
+
+void xbt_os_thread_set_specific(xbt_os_thread_key_t key, void* value) {
+
+  if (!TlsSetValue(key, value))
+    THROWF(system_error, (int) GetLastError(), "TlsSetValue() failed");
+}
+
+void* xbt_os_thread_get_specific(xbt_os_thread_key_t key) {
+  return TlsGetValue(key);
+}
+
 void xbt_os_thread_detach(xbt_os_thread_t thread)
 {
   THROW_UNIMPLEMENTED;