Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
authorSamuel Lepetit <samuel.lepetit@inria.fr>
Thu, 26 Apr 2012 15:24:24 +0000 (17:24 +0200)
committerSamuel Lepetit <samuel.lepetit@inria.fr>
Thu, 26 Apr 2012 15:24:24 +0000 (17:24 +0200)
21 files changed:
buildtools/Cmake/AddTests.cmake
doc/use.doc
examples/msg/io/io.tesh [new file with mode: 0644]
examples/msg/masterslave/masterslave_kill.c
examples/msg/masterslave/masterslave_kill.tesh
include/instr/instr.h
include/xbt/dynar.h
include/xbt/function_types.h
src/instr/instr_interface.c
src/instr/instr_private.h
src/instr/instr_routing.c
src/msg/msg_process.c
src/simix/smx_global.c
src/simix/smx_host.c
src/simix/smx_private.h
src/simix/smx_process.c
src/simix/smx_smurf.c
src/simix/smx_user.c
src/surf/maxmin.c
src/xbt/dynar.c
tools/gras/struct_diff.c

index 394d859..8adab59 100644 (file)
@@ -124,6 +124,8 @@ ADD_TEST(tesh-simdag-par-1          ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}     --setenv
 ADD_TEST(tesh-simdag-par-2             ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}     --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite       --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/partask/test_comp_only_par.tesh)
 
 # MSG examples
+ADD_TEST(msg-file      ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/ --setenv srcdir=${CMAKE_HOME_DIRECTORY}/ --cd ${CMAKE_HOME_DIRECTORY}/examples/ ${CMAKE_HOME_DIRECTORY}/examples/msg/io/io.tesh)
+
 ADD_TEST(msg-sendrecv-CLM03-thread     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}     --cfg contexts/factory:thread           --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg    --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/sendrecv/sendrecv_CLM03.tesh)
 ADD_TEST(msg-sendrecv-Vegas-thread     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}     --cfg contexts/factory:thread           --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg    --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/sendrecv/sendrecv_Vegas.tesh)
 ADD_TEST(msg-sendrecv-Reno-thread      ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION}     --cfg contexts/factory:thread           --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg    --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/sendrecv/sendrecv_Reno.tesh)
index cb1cf02..b32b002 100644 (file)
@@ -6,7 +6,12 @@ If you don't know were to look to start with, you should probably have
 a look at the following presentation first to get the basic concepts.
 Afterward, you probably want to proceed to the \ref MSG_API. Of
 course, if you're curious or if you know what you want, you may prefer
-to go to \ref SMPI_API, or even \ref GRAS_API.
+to go to \ref SMPI_API, or even \ref GRAS_API. 
+
+The scientific bases of the SimGrid project are presented in a 3 ou 4
+hours-long tutorial. It can be found at the following locations.
+ - https://gforge.inria.fr/plugins/scmgit/cgi-bin/gitweb.cgi?p=simgrid/propaganda.git;a=blob_plain;f=tutorial/simgrid-tutorial.pdf;hb=HEAD
+ - http://webloria.loria.fr/~quinson/blog/2010/0628/Tutorial_at_HPCS/
 
 \latexonly
 \includepdf[nup=2x4,pages=1-]{../webcruft/simgrid-101.pdf}
diff --git a/examples/msg/io/io.tesh b/examples/msg/io/io.tesh
new file mode 100644 (file)
index 0000000..4356685
--- /dev/null
@@ -0,0 +1,34 @@
+#! ./tesh
+
+$ ${bindir:=.}/io/file ${srcdir:=.}/examples/platforms/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (0:@) Configuration change: Set 'path' to '../examples/platforms/'
+> [  0.000000] (0:@) Create resource with Bconnection '6000000000' Bread '100000000' Bwrite '30000000'
+> [  0.000000] (0:@) Create resource with Bconnection '6000000000' Bread '100000000' Bwrite '30000000'
+> [  0.000000] (0:@) Create resource with Bconnection '6000000000' Bread '100000000' Bwrite '30000000'
+> [  0.000000] (0:@) Create resource with Bconnection '6000000000' Bread '100000000' Bwrite '30000000'
+> [  0.000000] (0:@) Number of host '4'
+> [  0.000000] (1:0@denise)    Open file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000000] (2:1@alice)     Open file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml'
+> [  0.000000] (3:2@carl)      Open file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml'
+> [  0.000000] (4:3@bob)       Open file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml'
+> [  0.000005] (2:1@alice)     Having read  482        on /home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml
+> [  0.000040] (4:3@bob)       Having read  4028       on /home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml
+> [  0.000170] (1:0@denise)    Having read  17028      on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml
+> [  0.000226] (3:2@carl)      Having read  22645      on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml
+> [  0.003338] (2:1@alice)     Having write 100000     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml
+> [  0.003374] (4:3@bob)       Having write 100000     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml
+> [  0.003504] (1:0@denise)    Having write 100000     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml
+> [  0.003560] (3:2@carl)      Having write 100000     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml
+> [  0.004343] (2:1@alice)     Having read  100482     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml
+> [  0.004343] (2:1@alice)     File /home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml Size 100482
+> [  0.004343] (2:1@alice)     Close file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/One_cluster_no_backbone.xml'
+> [  0.004414] (4:3@bob)       Having read  104028     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml
+> [  0.004414] (4:3@bob)       File /home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml Size 104028
+> [  0.004414] (4:3@bob)       Close file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/nancy.xml'
+> [  0.004674] (1:0@denise)    Having read  117028     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml
+> [  0.004674] (1:0@denise)    File /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml Size 117028
+> [  0.004674] (1:0@denise)    Close file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k.xml'
+> [  0.004786] (3:2@carl)      Having read  122645     on /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml
+> [  0.004786] (3:2@carl)      File /home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml Size 122645
+> [  0.004786] (3:2@carl)      Close file '/home/user/Install/simgrid/doc/simgrid/examples/platforms/g5k_cabinets.xml'
+> [  0.004786] (0:@) Simulation time 0.00478623
\ No newline at end of file
index c65c06b..7baf1e6 100644 (file)
@@ -16,8 +16,9 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
 static int slave(int argc, char *argv[])
 {
   XBT_INFO("Hello!");
-  XBT_INFO("Suspend process");
+  XBT_INFO("Suspending myself");
   MSG_process_suspend(MSG_process_self());
+  XBT_INFO("OK, OK. Let's work");
   MSG_task_execute(MSG_task_create("toto", 1e9, 0, NULL));
   XBT_INFO("Bye!");
   return 0;
index 2db6f37..3e58ef7 100644 (file)
@@ -2,11 +2,12 @@
 
 p Testing a simple master/slave example application
 
-$ $SG_TEST_EXENV masterslave/masterslave_kill$EXEEXT ${srcdir:=.}/masterslave/platform_kill.xml ${srcdir:=.}/masterslave/deployment_masterslave_kill.xml
+$ $SG_TEST_EXENV masterslave/masterslave_kill$EXEEXT ${srcdir:=.}/masterslave/platform_kill.xml ${srcdir:=.}/masterslave/deployment_masterslave_kill.xml --log=surf_maxmin.thres:error
 > [alice:master:(1) 0.000000] [msg_test/INFO] Hello!
 > [bob:slave:(2) 0.000000] [msg_test/INFO] Hello!
-> [bob:slave:(2) 0.000000] [msg_test/INFO] Suspend process
+> [bob:slave:(2) 0.000000] [msg_test/INFO] Suspending myself
 > [alice:master:(1) 10.000000] [msg_test/INFO] Resume process
+> [bob:slave:(2) 10.000000] [msg_test/INFO] OK, OK. Let's work
 > [alice:master:(1) 10.000000] [msg_test/INFO] Kill process
 > [alice:master:(1) 10.000000] [msg_test/INFO] OK, goodbye now.
 > [10.000000] [msg_test/INFO] Simulation time 10
\ No newline at end of file
index da7491c..ccd354e 100644 (file)
@@ -69,6 +69,11 @@ XBT_PUBLIC(void) TRACE_link_srcdst_variable_set_with_time (double time, const ch
 XBT_PUBLIC(void) TRACE_link_srcdst_variable_add_with_time (double time, const char *src, const char *dst, const char *variable, double value);
 XBT_PUBLIC(void) TRACE_link_srcdst_variable_sub_with_time (double time, const char *src, const char *dst, const char *variable, double value);
 XBT_PUBLIC(xbt_dynar_t) TRACE_get_link_variables (void);
+XBT_PUBLIC(void) TRACE_host_state_declare (const char *state);
+XBT_PUBLIC(void) TRACE_host_state_declare_value (const char *state, const char *value, const char *color);
+XBT_PUBLIC(void) TRACE_host_set_state (const char *host, const char *state, const char *value);
+XBT_PUBLIC(void) TRACE_host_push_state (const char *host, const char *state, const char *value);
+XBT_PUBLIC(void) TRACE_host_pop_state (const char *host, const char *state);
 
 /* for creating graph configuration files for Triva by hand */
 XBT_PUBLIC(xbt_dynar_t) TRACE_get_node_types (void);
index 382c643..c86b868 100644 (file)
@@ -97,6 +97,8 @@ XBT_PUBLIC(unsigned int) xbt_dynar_search(xbt_dynar_t const dynar, void *elem);
 XBT_PUBLIC(int) xbt_dynar_member(xbt_dynar_t const dynar, void *elem);
 XBT_PUBLIC(void) xbt_dynar_sort(xbt_dynar_t const dynar,
                                 int_f_cpvoid_cpvoid_t compar_fn);
+XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar,
+    int_f_pvoid_t color);
 XBT_PUBLIC(int) xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2,
                                   int(*compar)(const void *, const void *));
 XBT_PUBLIC(void *) xbt_dynar_to_array (xbt_dynar_t dynar);
index d140c97..fc1b458 100644 (file)
@@ -21,6 +21,7 @@ typedef void *(*pvoid_f_pvoid_t) (void *);
 typedef void (*void_f_void_t) (void);
 
 typedef int (*int_f_void_t) (void);
+typedef int (*int_f_pvoid_t) (void*);
 
 typedef int (*int_f_pvoid_pvoid_t) (void *, void *);
 typedef int (*int_f_cpvoid_cpvoid_t) (const void *, const void *);
index a24ded0..26daa66 100644 (file)
@@ -787,6 +787,102 @@ xbt_dynar_t TRACE_get_link_variables (void)
   return instr_dict_to_dynar (user_link_variables);
 }
 
+/** \ingroup TRACE_user_variables
+ *  \brief Declare a new user state associated to hosts.
+ *
+ *  Declare a user state that will be associated to hosts.
+ *  A user host state can be used to trace application states.
+ *
+ *  \param state The name of the new state to be declared.
+ *
+ *  \see TRACE_host_state_declare_value
+ */
+void TRACE_host_state_declare (const char *state)
+{
+  instr_new_user_state_type("HOST", state);
+}
+
+/** \ingroup TRACE_user_variables
+ *  \brief Declare a new value for a user state associated to hosts.
+ *
+ *  Declare a value for a state. The color needs to be
+ *  a string with three numbers separated by spaces in the range [0,1].
+ *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
+ *
+ *  \param state The name of the new state to be declared.
+ *  \param value The name of the value
+ *  \param color The color of the value
+ *
+ *  \see TRACE_host_state_declare
+ */
+void TRACE_host_state_declare_value (const char *state, const char *value, const char *color)
+{
+  instr_new_value_for_user_state_type (state, value, color);
+}
+
+/** \ingroup TRACE_user_variables
+ *  \brief Set the user state to the given value.
+ *
+ *  Change a user state previously declared to the given value.
+ *
+ *  \param host The name of the host to be considered.
+ *  \param state The name of the state previously declared.
+ *  \param value The new value of the state.
+ *
+ *  \see TRACE_host_state_declare, TRACE_host_push_state, TRACE_host_pop_state
+ */
+void TRACE_host_set_state (const char *host, const char *state, const char *value)
+{
+  container_t container = PJ_container_get(host);
+  type_t type = PJ_type_get (state, container->type);
+  val_t val = PJ_value_get (value, type);
+  if (val == NULL){
+    //if user didn't declare a value with a color, user a NULL color
+    PJ_value_new (value, NULL, type);
+  }
+  new_pajeSetState(MSG_get_clock(), container, type, val);
+}
+
+/** \ingroup TRACE_user_variables
+ *  \brief Push a new value for a state of a given host.
+ *
+ *  Change a user state previously declared by pushing the new value to the state.
+ *
+ *  \param host The name of the host to be considered.
+ *  \param state The name of the state previously declared.
+ *  \param value The value to be pushed.
+ *
+ *  \see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_pop_state
+ */
+void TRACE_host_push_state (const char *host, const char *state, const char *value)
+{
+  container_t container = PJ_container_get(host);
+  type_t type = PJ_type_get (state, container->type);
+  val_t val = PJ_value_get (value, type);
+  if (val == NULL){
+    //if user didn't declare a value with a color, user a NULL color
+    PJ_value_new (value, NULL, type);
+  }
+  new_pajePushState(MSG_get_clock(), container, type, val);
+}
+
+/** \ingroup TRACE_user_variables
+ *  \brief Pop the last value of a state of a given host.
+ *
+ *  Change a user state previously declared by removing the last value of the state.
+ *
+ *  \param host The name of the host to be considered.
+ *  \param state The name of the state to be popped.
+ *
+ *  \see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_push_state
+ */
+void TRACE_host_pop_state (const char *host, const char *state)
+{
+  container_t container = PJ_container_get(host);
+  type_t type = PJ_type_get (state, container->type);
+  new_pajePopState(MSG_get_clock(), container, type);
+}
+
 /** \ingroup TRACE_API
  *  \brief Get Paje container types that can be mapped to the nodes of a graph.
  *
index e61edea..76cba92 100644 (file)
@@ -226,6 +226,8 @@ void PJ_value_free (val_t value);
 void instr_routing_define_callbacks (void);
 void instr_new_variable_type (const char *new_typename, const char *color);
 void instr_new_user_variable_type  (const char *father_type, const char *new_typename, const char *color);
+void instr_new_user_state_type (const char *father_type, const char *new_typename);
+void instr_new_value_for_user_state_type (const char *typename, const char *value, const char *color);
 int instr_platform_traced (void);
 xbt_graph_t instr_routing_platform_graph (void);
 void instr_routing_platform_graph_export_graphviz (xbt_graph_t g, const char *filename);
index d2c91ee..5006b68 100644 (file)
@@ -396,7 +396,41 @@ void instr_new_user_variable_type  (const char *father_type, const char *new_typ
   recursiveNewUserVariableType (father_type, new_typename, color, PJ_type_get_root());
 }
 
+static void recursiveNewUserStateType (const char *father_type, const char *new_typename, type_t root)
+{
+  if (!strcmp (root->name, father_type)){
+    PJ_type_state_new (new_typename, root);
+  }
+  xbt_dict_cursor_t cursor = NULL;
+  type_t child_type;
+  char *name;
+  xbt_dict_foreach(root->children, cursor, name, child_type) {
+    recursiveNewUserStateType (father_type, new_typename, child_type);
+  }
+}
+
+void instr_new_user_state_type (const char *father_type, const char *new_typename)
+{
+  recursiveNewUserStateType (father_type, new_typename, PJ_type_get_root());
+}
 
+static void recursiveNewValueForUserStateType (const char *typename, const char *value, const char *color, type_t root)
+{
+  if (!strcmp (root->name, typename)){
+    PJ_value_new (value, color, root);
+  }
+  xbt_dict_cursor_t cursor = NULL;
+  type_t child_type;
+  char *name;
+  xbt_dict_foreach(root->children, cursor, name, child_type) {
+    recursiveNewValueForUserStateType (typename, value, color, child_type);
+  }
+}
+
+void instr_new_value_for_user_state_type (const char *typename, const char *value, const char *color)
+{
+  recursiveNewValueForUserStateType (typename, value, color, PJ_type_get_root());
+}
 
 int instr_platform_traced ()
 {
index 8f73cbb..43b782b 100644 (file)
@@ -206,11 +206,11 @@ void MSG_process_kill(m_process_t process)
   TRACE_msg_process_kill(process);
 #endif
 
-  /* FIXME: why do we only cancel communication actions? is this useful? */
-  simdata_process_t p_simdata = simcall_process_get_data(process);
-  if (p_simdata->waiting_task && p_simdata->waiting_task->simdata->comm) {
-    simcall_comm_cancel(p_simdata->waiting_task->simdata->comm);
-  }
+//  /* FIXME: why do we only cancel communication actions? is this useful? */
+//  simdata_process_t p_simdata = simcall_process_get_data(process);
+//  if (p_simdata->waiting_task && p_simdata->waiting_task->simdata->comm) {
+//    simcall_comm_cancel(p_simdata->waiting_task->simdata->comm);
+//  }
  
   simcall_process_kill(process);
 
index 2c3b8d7..e25a863 100644 (file)
@@ -165,6 +165,14 @@ XBT_INLINE double SIMIX_get_clock(void)
   }
 }
 
+int process_syscall_color(void *p) {
+  e_smx_simcall_t s = (*((smx_process_t *)p))->simcall.call;
+
+  if (s == SIMCALL_NONE || s == SIMCALL_PROCESS_KILL) return 2;
+  else if (s == SIMCALL_PROCESS_RESUME)  return 1;
+  else return 0;
+}
+
 void SIMIX_run(void)
 {
   double time = 0;
@@ -185,6 +193,7 @@ void SIMIX_run(void)
       XBT_DEBUG("New Sub-Schedule Round; size(queue)=%lu",
               xbt_dynar_length(simix_global->process_to_run));
       SIMIX_process_runall();
+      xbt_dynar_three_way_partition(simix_global->process_that_ran, process_syscall_color);
       xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
         if (process->simcall.call != SIMCALL_NONE) {
           SIMIX_simcall_pre(&process->simcall, 0);
index 08b7ebe..d3be3ca 100644 (file)
@@ -326,7 +326,7 @@ void SIMIX_host_execution_suspend(smx_action_t action)
 void SIMIX_host_execution_resume(smx_action_t action)
 {
   if(action->execution.surf_exec)
-    surf_workstation_model->suspend(action->execution.surf_exec);
+    surf_workstation_model->resume(action->execution.surf_exec);
 }
 
 void SIMIX_execution_finish(smx_action_t action)
index 824239f..61acf3b 100644 (file)
@@ -185,6 +185,8 @@ static XBT_INLINE e_smx_state_t SIMIX_action_map_state(e_surf_action_state_t sta
   }
 }
 
+int process_syscall_color(void *p);
+
 void SIMIX_context_mod_init(void);
 void SIMIX_context_mod_exit(void);
 
index 7c54b7a..215e06a 100644 (file)
@@ -96,6 +96,7 @@ void SIMIX_process_cleanup(smx_process_t process)
   xbt_swag_remove(process, simix_global->process_list);
   xbt_swag_remove(process, process->smx_host->process_list);
   xbt_swag_insert(process, simix_global->process_to_destroy);
+  process->context->iwannadie = 0;
 }
 
 /** 
@@ -288,8 +289,8 @@ void SIMIX_process_kill(smx_process_t process) {
         break;
     }
   }
-
-  xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
+  if(!xbt_dynar_member(simix_global->process_to_run, &(process)))
+    xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
 }
 
 /**
@@ -380,12 +381,8 @@ void SIMIX_process_resume(smx_process_t process, smx_process_t issuer)
 {
   xbt_assert((process != NULL), "Invalid parameters");
 
-  if (!process->suspended) {
-    XBT_DEBUG("Process '%s' is not suspended", process->name);
-    return;
-  }
-
-  process->suspended = 0;
+  if(process->context->iwannadie) return;
+    process->suspended = 0;
 
   /* If we are resuming another process, resume the action it was waiting for
      if any. Otherwise add it to the list of process to run in the next round. */
@@ -414,7 +411,8 @@ void SIMIX_process_resume(smx_process_t process, smx_process_t issuer)
       }
     }
     else {
-      xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
+      if(!xbt_dynar_member(simix_global->process_to_run, &(process)))
+        xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, process);
     }
   }
 }
index 4e7c79d..df7fb25 100644 (file)
@@ -33,7 +33,10 @@ void SIMIX_simcall_answer(smx_simcall_t simcall)
     XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall->call), (int)simcall->call,
         simcall->issuer->name, simcall->issuer);
     simcall->issuer->simcall.call = SIMCALL_NONE;
-    xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, simcall->issuer);
+    if(!xbt_dynar_member(simix_global->process_to_run, &(simcall->issuer)))
+      xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, simcall->issuer);
+    else
+      DIE_IMPOSSIBLE;
   }
 }
 
index 1f5f4b4..c0198ab 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "smx_private.h"
 #include "mc/mc.h"
+#include "xbt/ex.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
 
@@ -1078,6 +1079,8 @@ void simcall_cond_wait_timeout(smx_cond_t cond,
                                  smx_mutex_t mutex,
                                  double timeout)
 {
+  xbt_ex_t e;
+
   xbt_assert(isfinite(timeout), "timeout is not finite!");
   
   smx_simcall_t simcall = SIMIX_simcall_mine();
@@ -1087,7 +1090,20 @@ void simcall_cond_wait_timeout(smx_cond_t cond,
   simcall->cond_wait_timeout.mutex = mutex;
   simcall->cond_wait_timeout.timeout = timeout;
 
-  SIMIX_simcall_push(simcall->issuer);
+  TRY {
+    SIMIX_simcall_push(simcall->issuer);
+  }
+  CATCH(e) {
+    switch (e.category) {
+      case timeout_error:
+        simcall->issuer->waiting_action = NULL; // FIXME: should clean ?
+        break;
+      default:
+        break;
+    }
+    RETHROW;
+    xbt_ex_free(e);
+  }
 }
 
 void simcall_cond_broadcast(smx_cond_t cond)
index 349093c..ac38be5 100644 (file)
@@ -227,7 +227,8 @@ lmm_variable_t lmm_variable_new(lmm_system_t sys, void *id,
     xbt_swag_insert_at_head(var, &(sys->variable_set));
   else
     xbt_swag_insert_at_tail(var, &(sys->variable_set));
-  XBT_OUT();
+
+  XBT_LOG(xbt_log_priority_trace, "<< end of %s returns %p", _XBT_FUNCTION, var);
   return var;
 }
 
index 7e6f015..7e7512b 100644 (file)
@@ -720,6 +720,54 @@ XBT_INLINE void xbt_dynar_sort(xbt_dynar_t dynar,
   _dynar_unlock(dynar);
 }
 
+/** @brief Sorts a dynar according to their color assuming elements can have only three colors.
+ * Since there are only three colors, it is linear and much faster than a classical sort.
+ * See for example http://en.wikipedia.org/wiki/Dutch_national_flag_problem
+ *
+ * \param dynar the dynar to sort
+ * \param color the color function of type (int (compar_fn*) (void*) (void*)). The return value of color is assumed to be 0, 1, or 2.
+ *
+ * At the end of the call, elements with color 0 are at the beginning of the dynar, elements with color 2 are at the end and elements with color 1 are in the middle.
+ *
+ * Remark: if the elements stored in the dynar are structures, the color
+ * function has to retrieve the field to sort first.
+ */
+XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar,
+                                               int_f_pvoid_t color)
+{
+  _dynar_lock(dynar);
+  unsigned long size = xbt_dynar_length(dynar);
+  void *data = dynar->data;
+  unsigned long int i;
+  unsigned long int p = -1;
+  unsigned long int q = size;
+  unsigned long elmsize = dynar->elmsize;
+  void *tmp = xbt_malloc(elmsize);
+
+#define swap(a,b) do {     \
+    memcpy(tmp,  a , elmsize);  \
+    memcpy( a ,  b , elmsize);  \
+    memcpy( b , tmp, elmsize);  \
+  } while(0)
+
+  for (i = 0; i < q;) {
+    unsigned long int datai = ((unsigned long int) data) + i*elmsize;
+    int colori = color((void *) datai);
+
+    if(colori==0) {
+      unsigned long int datap = ((unsigned long int) data) + (++p)*elmsize;
+      swap((void *) datai, (void *) datap);
+      ++i;
+    } else if (colori==2) {
+      unsigned long int dataq = ((unsigned long int) data) + (--q)*elmsize;
+      swap((void *) datai, (void *) dataq);
+    } else {
+      ++i;
+    }
+  }
+  _dynar_unlock(dynar);
+}
+
 /** @brief Transform a dynar into a NULL terminated array
  *
  * \param dynar the dynar to transform
index 9c78251..edb9aec 100644 (file)
@@ -144,14 +144,14 @@ int main(int argc, char** argv) {
       if (field->offset[GRAS_THISARCH]<= offset&&
           field->offset[GRAS_THISARCH]+field->type->size[GRAS_THISARCH] >= offset) {
         found = 1;
-        printf("This offset is somewhere in field %s, which starts at offset %zu and is of size %zu\n",
+        printf("This offset is somewhere in field %s, which starts at offset %ld and is of size %ld\n",
               field->name,field->offset[GRAS_THISARCH],field->type->size[GRAS_THISARCH]);
 
       }
     }
     if (!found) {
 
-      printf("Damnit, the structure is too short to find the the field (last field %s was at offset %zu, with size %zu). Weird.\n",
+      printf("Damnit, the structure is too short to find the the field (last field %s was at offset %ld, with size %ld). Weird.\n",
           field->name,field->offset[GRAS_THISARCH],field->type->size[GRAS_THISARCH]);
     }
   }