Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove xbt_parmap_get_worker_id to simplify the parmap interface
[simgrid.git] / src / simix / smx_context_raw.c
index 5cf7c07..432c972 100644 (file)
@@ -30,7 +30,9 @@ typedef struct s_smx_ctx_raw {
 
 #ifdef CONTEXT_THREADS
 static xbt_parmap_t raw_parmap;
-static raw_stack_t* raw_local_maestro_stacks; /* space to save maestro's stack in each thread */
+static raw_stack_t* raw_workers_stacks;       /* space to save the worker stack in each thread */
+static unsigned long raw_threads_working;     /* number of threads that have started their work */
+static xbt_os_thread_key_t raw_worker_id_key; /* thread-specific storage for the thread id */
 #endif
 
 static unsigned long raw_process_index = 0;   /* index of the next process to run in the
@@ -226,7 +228,8 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
 #ifdef CONTEXT_THREADS
     int nthreads = SIMIX_context_get_nthreads();
     raw_parmap = xbt_parmap_new(nthreads);
-    raw_local_maestro_stacks = xbt_new(raw_stack_t, nthreads);
+    raw_workers_stacks = xbt_new(raw_stack_t, nthreads);
+    xbt_os_thread_key_create(&raw_worker_id_key);
 #endif
     if (SIMIX_context_get_parallel_threshold() > 1) {
       /* choose dynamically */
@@ -259,7 +262,7 @@ static int smx_ctx_raw_factory_finalize(smx_context_factory_t *factory)
 #ifdef CONTEXT_THREADS
   if (raw_parmap)
     xbt_parmap_destroy(raw_parmap);
-  xbt_free(raw_local_maestro_stacks);
+  xbt_free(raw_workers_stacks);
 #endif
   return smx_ctx_base_factory_finalize(factory);
 }
@@ -428,7 +431,7 @@ void smx_ctx_raw_new_sr(void)
 #else
 static void smx_ctx_raw_runall_serial(void)
 {
-  if (xbt_dynar_length(simix_global->process_to_run) > 0) {
+  if (!xbt_dynar_is_empty(simix_global->process_to_run)) {
     smx_process_t first_process =
         xbt_dynar_get_as(simix_global->process_to_run, 0, smx_process_t);
     raw_process_index = 1;
@@ -463,8 +466,11 @@ static void smx_ctx_raw_suspend_parallel(smx_context_t context)
     /* all processes were run, go to the barrier */
     XBT_DEBUG("No more processes to run");
     next_context = (smx_context_t) raw_maestro_context;
-    unsigned long worker_id = xbt_parmap_get_worker_id(raw_parmap);
-    next_stack = raw_local_maestro_stacks[worker_id];
+    unsigned long worker_id =
+        (unsigned long) xbt_os_thread_get_specific(raw_worker_id_key);
+    XBT_DEBUG("Restoring worker stack %lu (working threads = %lu)",
+        worker_id, raw_threads_working);
+    next_stack = raw_workers_stacks[worker_id];
   }
 
   SIMIX_context_set_current(next_context);
@@ -475,18 +481,21 @@ static void smx_ctx_raw_suspend_parallel(smx_context_t context)
 static void smx_ctx_raw_resume_parallel(smx_process_t first_process)
 {
 #ifdef CONTEXT_THREADS
-  unsigned long worker_id = xbt_parmap_get_worker_id(raw_parmap);
-  raw_stack_t* local_maestro_stack = &raw_local_maestro_stacks[worker_id];
+  unsigned long worker_id = __sync_fetch_and_add(&raw_threads_working, 1);
+  xbt_os_thread_set_specific(raw_worker_id_key, (void*) worker_id);
+  XBT_DEBUG("Saving worker stack %lu", worker_id);
+  raw_stack_t* worker_stack = &raw_workers_stacks[worker_id];
 
   smx_context_t context = first_process->context;
   SIMIX_context_set_current(context);
-  raw_swapcontext(local_maestro_stack, ((smx_ctx_raw_t) context)->stack_top);
+  raw_swapcontext(worker_stack, ((smx_ctx_raw_t) context)->stack_top);
 #endif
 }
 
 static void smx_ctx_raw_runall_parallel(void)
 {
 #ifdef CONTEXT_THREADS
+  raw_threads_working = 0;
   xbt_parmap_apply(raw_parmap, (void_f_pvoid_t) smx_ctx_raw_resume_parallel,
       simix_global->process_to_run);
 #endif