Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
In trace replay, allow to have one trace file per process
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 27 Feb 2010 23:06:55 +0000 (23:06 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 27 Feb 2010 23:06:55 +0000 (23:06 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7145 48e7efb5-ca39-0410-a469-dd3cf9ba447f

ChangeLog
examples/msg/actions/actions.c
src/msg/msg_actions.c

index 90b8f50..e59ed15 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,5 @@
 SimGrid (3.3.5-svn) unstable; urgency=low
 
- SimDag:
-  * Kill the useless "rate" argument of SD_task_get_execution_time()
-    Everyone used to provide -1 as a value, it was not used, and the
-    semantic of a possible use wasn't even clear.
  Java Bindings: Various Cleanups
   * Remove put/get: no need to export deprecated interface in Java
     Use send/receive instead.
@@ -13,7 +9,16 @@ SimGrid (3.3.5-svn) unstable; urgency=low
   * Make JniException a runtime exception, so that there is no need to
     declare the fact that you may encounter such a beast. I guess that
     nobody will ever want to survive such error.
-
+ SimDag:
+  * Kill the useless "rate" argument of SD_task_get_execution_time()
+    Everyone used to provide -1 as a value, it was not used, and the
+    semantic of a possible use wasn't even clear.
+ MSG: 
+  * In trace replay, allow to have one trace file per process.
+    Give the specific trace file as argument of each process, 
+      and call MSG_action_trace_run(NULL)
+    You can still have one merged file for each processes.
+      
  -- Da SimGrid team <simgrid-devel@lists.gforge.inria.fr>
 
 
index 9661ad1..44bfb41 100644 (file)
@@ -451,9 +451,11 @@ int main(int argc, char *argv[])
   
   /* Check the given arguments */
   MSG_global_init(&argc, argv);
-  if (argc < 4) {
-    printf("Usage: %s platform_file deployment_file action_files\n", argv[0]);
-    printf("example: %s msg_platform.xml msg_deployment.xml actions\n",
+  if (argc < 3) {
+    printf("Usage: %s platform_file deployment_file [action_files]\n", argv[0]);
+    printf("example: %s msg_platform.xml msg_deployment.xml actions # if all actions are in the same file\n",
+           argv[0]);
+    printf("example: %s msg_platform.xml msg_deployment.xml # if actions are in separate files, specified in deployment\n",
            argv[0]);
     exit(1);
   }
@@ -480,7 +482,7 @@ int main(int argc, char *argv[])
 
 
   /* Actually do the simulation using MSG_action_trace_run */
-  res = MSG_action_trace_run(argv[3]);
+  res = MSG_action_trace_run(argv[3]); // it's ok to pass a NULL argument here
 
   INFO1("Simulation time %g", MSG_get_clock());
   MSG_clean();
index f542748..58f96b0 100644 (file)
@@ -13,6 +13,11 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_action,msg,"MSG actions for trace driven sim
 static xbt_dict_t action_funs;
 static xbt_dict_t action_queues;
 
+/* To split the file if a unique one is given (specific variable for the other case live in runner()) */
+static FILE *action_fp=NULL;
+static char *action_line = NULL;
+static size_t action_len = 0;
+
 static xbt_dynar_t action_get_action(char *name);
 
 /** \ingroup msg_actions
@@ -41,17 +46,51 @@ void MSG_action_unregister(const char *action_name)
   xbt_dict_remove(action_funs, action_name);
 }
 
-static int MSG_action_runner(int argc, char *argv[])
-{
+static int MSG_action_runner(int argc, char *argv[]) {
   xbt_dynar_t evt=NULL;
+  if (action_fp) { // A unique trace file
 
-  while ((evt = action_get_action(argv[0]))) {
-    msg_action_fun function =
-        xbt_dict_get(action_funs, xbt_dynar_get_as(evt, 1, char *));
-    (*function) (evt);
-    xbt_dynar_free(&evt);
-  }
+    while ((evt = action_get_action(argv[0]))) {
+      msg_action_fun function =
+          xbt_dict_get(action_funs, xbt_dynar_get_as(evt, 1, char *));
+      (*function) (evt);
+      xbt_dynar_free(&evt);
+    }
+  } else { // Should have got my trace file in argument
+    xbt_assert0(argc>=2,
+          "No simulation-wide trace file provided to MSG_action_trace_run(), "
+          "and no process-wide trace file provided in deployment file. Aborting."
+    );
+
+    char *line = NULL;
+    size_t line_len = 0;
+    FILE *fp = fopen(argv[1], "r");
+    xbt_assert2(fp != NULL, "Cannot open %s: %s", argv[1], strerror(errno));
+
+    ssize_t read;
+    // Read lines and execute them until I reach the end of file
+    while ((read = getline(&line, &line_len, fp)) != -1) {
+      // cleanup and split the string I just read
+      char *comment = strchr(line, '#');
+      if (comment != NULL)
+        *comment = '\0';
+      xbt_str_trim(line, NULL);
+      if (line[0] == '\0')
+        continue;
+      evt = xbt_str_split_quoted(line);
 
+      char *evtname = xbt_dynar_get_as(evt, 0, char *);
+      if (!strcmp(argv[0],evtname)) {
+        msg_action_fun function =
+            xbt_dict_get(action_funs, xbt_dynar_get_as(evt, 1, char *));
+        (*function) (evt);
+      } else {
+        WARN1("Ignore trace element not for me: %s",xbt_str_join(evt," "));
+      }
+      xbt_dynar_free(&evt);
+    }
+
+  }
   return 0;
 }
 
@@ -67,9 +106,6 @@ void _MSG_action_exit() {
   xbt_dict_free(&action_funs);
 }
 
-static FILE *action_fp=NULL;
-static char *action_line = NULL;
-static size_t action_len = 0;
 
 static xbt_dynar_t action_get_action(char *name) {
   ssize_t read;
@@ -83,7 +119,8 @@ static xbt_dynar_t action_get_action(char *name) {
       goto todo_done;
     }
 
-    // Read lines until I reach something for me (which breaks in loop body) or end of file
+    // Read lines until I reach something for me (which breaks in loop body)
+    // or end of file reached
     while ((read = getline(&action_line, &action_len, action_fp)) != -1) {
       // cleanup and split the string I just read
       char *comment = strchr(action_line, '#');
@@ -108,7 +145,7 @@ static xbt_dynar_t action_get_action(char *name) {
         xbt_dynar_push(otherqueue,&evt);
       }
     }
-    goto todo_done; // end of file reached in vain while searching for more work
+    goto todo_done; // end of file reached while searching in vain for more work
   } else {
     // Get something from my queue and return it
     xbt_dynar_shift(myqueue,&evt);
@@ -116,7 +153,9 @@ static xbt_dynar_t action_get_action(char *name) {
   }
 
 
-  todo_done: // I did all my actions for me in the file. cleanup before leaving
+  // I did all my actions for me in the file (either I closed the file, or a colleague did)
+  // Let's cleanup before leaving
+  todo_done:
   if (myqueue != NULL) {
     xbt_dynar_free(&myqueue);
     xbt_dict_remove(action_queues,name);
@@ -127,15 +166,17 @@ static xbt_dynar_t action_get_action(char *name) {
 /** \ingroup msg_actions
  * \brief A trace loader
  *
- *  Load a trace file containing actions, and execute them.
+ *  If path!=NULL, load a trace file containing actions, and execute them.
+ *  Else, assume that each process gets the path in its deployment file
  */
 MSG_error_t MSG_action_trace_run(char *path)
 {
   MSG_error_t res;
 
-  action_fp = fopen(path, "r");
-  xbt_assert2(action_fp != NULL, "Cannot open %s: %s", path, strerror(errno));
-
+  if (path) {
+    action_fp = fopen(path, "r");
+    xbt_assert2(action_fp != NULL, "Cannot open %s: %s", path, strerror(errno));
+  }
   res = MSG_main();
 
   if (xbt_dict_size(action_queues)) {
@@ -151,7 +192,8 @@ MSG_error_t MSG_action_trace_run(char *path)
 
   if (action_line)
     free(action_line);
-  fclose(action_fp);
+  if (path)
+    fclose(action_fp);
   xbt_dict_free(&action_queues);
   action_queues = xbt_dict_new();