Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New actions for the time independent trace replay framework:
[simgrid.git] / src / simix / smx_context_raw.c
index c053cff..f2f0544 100644 (file)
@@ -6,8 +6,9 @@
 /* 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 "simix/private.h"
+#include "smx_private.h"
 #include "xbt/parmap.h"
+#include "mc/mc.h"
 
 #ifdef HAVE_VALGRIND_VALGRIND_H
 #  include <valgrind/valgrind.h>
@@ -23,14 +24,14 @@ typedef struct s_smx_ctx_raw {
 #ifdef HAVE_VALGRIND_VALGRIND_H
   unsigned int valgrind_stack_id; /* the valgrind stack id */
 #endif
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   unsigned int thread;            /* Just for measuring purposes */
 #endif
 } s_smx_ctx_raw_t, *smx_ctx_raw_t;
 
 #ifdef CONTEXT_THREADS
 static xbt_parmap_t raw_parmap;
-static raw_stack_t* raw_workers_stacks;       /* space to save the worker stack in each thread */
+static smx_ctx_raw_t* raw_workers_context;    /* space to save the worker context 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
@@ -97,10 +98,14 @@ __asm__ (
 );
 #elif PROCESSOR_x86_64
 __asm__ (
-#if defined(APPLE) || defined(_WIN32)
+#if defined(APPLE)
    ".text\n"
    ".globl _raw_makecontext\n"
    "_raw_makecontext:\n"
+#elif defined(_WIN32)
+   ".text\n"
+   ".globl raw_makecontext\n"
+   "raw_makecontext:\n"
 #else
    ".text\n"
    ".globl raw_makecontext\n"
@@ -128,10 +133,14 @@ __asm__ (
 );
 
 __asm__ (
-#if defined(APPLE) || defined(_WIN32)
+#if defined(APPLE)
    ".text\n"
    ".globl _raw_swapcontext\n"
    "_raw_swapcontext:\n"
+#elif defined(_WIN32)
+   ".text\n"
+   ".globl raw_swapcontext\n"
+   "raw_swapcontext:\n"
 #else
    ".text\n"
    ".globl raw_swapcontext\n"
@@ -184,7 +193,7 @@ void raw_swapcontext(raw_stack_t* old, raw_stack_t new) {
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
 
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
 #include "xbt/xbt_os_time.h"
 #define NUM_THREADS 4
 static xbt_os_timer_t timer;
@@ -218,6 +227,7 @@ static void smx_ctx_raw_runall(void);
  */
 void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
 {
+
   XBT_VERB("Using raw contexts. Because the glibc is just not good enough for us.");
   smx_ctx_base_factory_init(factory);
 
@@ -231,9 +241,11 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
   if (SIMIX_context_is_parallel()) {
 #ifdef CONTEXT_THREADS
     int nthreads = SIMIX_context_get_nthreads();
-    raw_parmap = xbt_parmap_new(nthreads, SIMIX_context_get_parallel_mode());
-    raw_workers_stacks = xbt_new(raw_stack_t, nthreads);
     xbt_os_thread_key_create(&raw_worker_id_key);
+    raw_parmap = xbt_parmap_new(nthreads, SIMIX_context_get_parallel_mode());
+    raw_workers_context = xbt_new(smx_ctx_raw_t, nthreads);
+    raw_maestro_context=NULL;
+
 #endif
     if (SIMIX_context_get_parallel_threshold() > 1) {
       /* choose dynamically */
@@ -251,7 +263,7 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
     (*factory)->runall = smx_ctx_raw_runall_serial;
     (*factory)->suspend = smx_ctx_raw_suspend_serial;
   }
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   timer = xbt_os_timer_new();
 #endif
 }
@@ -262,7 +274,7 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
  */
 static int smx_ctx_raw_factory_finalize(smx_context_factory_t *factory)
 {
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   XBT_CRITICAL("Total wasted time in %u SR: %lf", sr_count, time_wasted_sr);
   XBT_CRITICAL("Total wasted time in %u SSR: %lf", ssr_count, time_wasted_ssr);
 #endif
@@ -270,7 +282,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_workers_stacks);
+  xbt_free(raw_workers_context);
 #endif
   return smx_ctx_base_factory_finalize(factory);
 }
@@ -315,7 +327,12 @@ smx_ctx_raw_create_context(xbt_main_func_t code, int argc, char **argv,
 #endif                          /* HAVE_VALGRIND_VALGRIND_H */
 
      } else {
-       raw_maestro_context = context;
+       if(data != NULL && raw_maestro_context==NULL)
+         raw_maestro_context = context;
+
+       if(MC_is_active())
+         MC_ignore_heap(&(raw_maestro_context->stack_top), sizeof(raw_maestro_context->stack_top));
+
      }
 
      return (smx_context_t) context;
@@ -402,7 +419,7 @@ static void smx_ctx_raw_resume_serial(smx_process_t first_process)
       ((smx_ctx_raw_t) context)->stack_top);
 }
 
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
 static void smx_ctx_raw_runall_serial(xbt_dynar_t processes)
 {
   smx_process_t process;
@@ -476,30 +493,15 @@ void smx_ctx_raw_new_sr(void)
  */
 static void smx_ctx_raw_runall_serial(void)
 {
-  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;
+  smx_process_t first_process =
+      xbt_dynar_get_as(simix_global->process_to_run, 0, smx_process_t);
+  raw_process_index = 1;
 
-    /* execute the first process */
-    smx_ctx_raw_resume_serial(first_process);
-  }
+  /* execute the first process */
+  smx_ctx_raw_resume_serial(first_process);
 }
 #endif
 
-/**
- * \brief Stops a raw context.
- *
- * This function is called when the main function of the context if finished.
- *
- * \param context the context of the current worker thread
- */
-static void smx_ctx_raw_stop_parallel(smx_context_t context)
-{
-  smx_ctx_base_stop(context);
-  smx_ctx_raw_suspend_parallel(context);
-}
-
 /**
  * \brief Suspends a running context and resumes another one or returns to
  * the main function of the current worker thread.
@@ -522,12 +524,12 @@ static void smx_ctx_raw_suspend_parallel(smx_context_t context)
   else {
     /* 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 =
         (unsigned long) xbt_os_thread_get_specific(raw_worker_id_key);
+    next_context = (smx_context_t)raw_workers_context[worker_id];
     XBT_DEBUG("Restoring worker stack %lu (working threads = %lu)",
         worker_id, raw_threads_working);
-    next_stack = raw_workers_stacks[worker_id];
+    next_stack = ((smx_ctx_raw_t)next_context)->stack_top;
   }
 
   SIMIX_context_set_current(next_context);
@@ -545,8 +547,11 @@ static void smx_ctx_raw_resume_parallel(smx_process_t first_process)
 #ifdef CONTEXT_THREADS
   unsigned long worker_id = __sync_fetch_and_add(&raw_threads_working, 1);
   xbt_os_thread_set_specific(raw_worker_id_key, (void*) worker_id);
+  smx_ctx_raw_t worker_context = (smx_ctx_raw_t)SIMIX_context_self();
+  raw_workers_context[worker_id] = worker_context;
   XBT_DEBUG("Saving worker stack %lu", worker_id);
-  raw_stack_t* worker_stack = &raw_workers_stacks[worker_id];
+  raw_stack_t* worker_stack = &(worker_context)->stack_top;
+
 
   smx_context_t context = first_process->context;
   SIMIX_context_set_current(context);
@@ -563,6 +568,8 @@ static void smx_ctx_raw_runall_parallel(void)
   raw_threads_working = 0;
   xbt_parmap_apply(raw_parmap, (void_f_pvoid_t) smx_ctx_raw_resume_parallel,
       simix_global->process_to_run);
+#else
+  xbt_die("You asked for a parallel execution, but you don't have any threads.")
 #endif
 }