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;
/* 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;
}
}
-
-
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);
#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"
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;
}
}
}
+
+#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
}
/**
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
+}
+
#include "xbt/function_types.h"
#include "simix/simix.h"
#include "simix/context.h"
+#include "simix/private.h"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(bindings);
context->argc = argc;
context->argv = argv;
context->code = code;
- }else{
- smx_current_context = context;
+ } else {
+ SIMIX_context_set_current(context);
}
context->data = data;
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)
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);
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);
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(){
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);
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);
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");
}
{
/*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)