From: suter Date: Fri, 8 Jun 2012 12:56:15 +0000 (+0200) Subject: First step to move trace replay from MSG towards SMPI X-Git-Tag: v3_8~644^2~2 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/6c6d22019a29d1a1e7cd1f52dbb21cf3d330c57c?hp=48a06dfd54aa94446d88653fff8a5ba8ce6e4add First step to move trace replay from MSG towards SMPI start by moving what isn't connected to MSG into xbt had to change some file names as xbt_replay_trace_* was a too long prefix and files are no more limited to the trace reader only. --- diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index ef6012d616..e5ad685b03 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -182,7 +182,7 @@ set(XBT_SRC src/xbt/graphxml_parse.c src/xbt/setset.c src/xbt/parmap.c - src/xbt/xbt_replay_trace_reader.c + src/xbt/xbt_replay.c src/xbt/lib.c src/xbt/automaton.c src/xbt/datadesc/ddt_create.c @@ -425,7 +425,7 @@ set(headers_to_install include/xbt/queue.h include/xbt/setset.h include/xbt/mmalloc.h - include/xbt/replay_trace_reader.h + include/xbt/replay.h include/xbt/parmap.h include/xbt/automaton.h include/xbt/automatonparse_promela.h diff --git a/examples/msg/actions/actions.c b/examples/msg/actions/actions.c index e45e988dde..ccd84bf69a 100644 --- a/examples/msg/actions/actions.c +++ b/examples/msg/actions/actions.c @@ -25,7 +25,7 @@ * C file, and the events to react to in a separate text file. * Declare a function handling each of the events that you want to * accept in your trace files, register them using \ref - * MSG_action_register in your main, and then use \ref + * xbt_replay_action_register in your main, and then use \ref * MSG_action_trace_run to launch the simulation. You can either * have one trace file containing all your events, or a file per * simulated process. Check the tesh files in the example directory @@ -568,20 +568,20 @@ int main(int argc, char *argv[]) MSG_launch_application(argv[2]); /* Action registration */ - MSG_action_register("init", action_init); - MSG_action_register("finalize", action_finalize); - MSG_action_register("comm_size",action_comm_size); - MSG_action_register("send", action_send); - MSG_action_register("Isend", action_Isend); - MSG_action_register("recv", action_recv); - MSG_action_register("Irecv", action_Irecv); - MSG_action_register("wait", action_wait); - MSG_action_register("barrier", action_barrier); - MSG_action_register("bcast", action_bcast); - MSG_action_register("reduce", action_reduce); - MSG_action_register("allReduce",action_allReduce); - MSG_action_register("sleep", action_sleep); - MSG_action_register("compute", action_compute); + xbt_replay_action_register("init", action_init); + xbt_replay_action_register("finalize", action_finalize); + xbt_replay_action_register("comm_size",action_comm_size); + xbt_replay_action_register("send", action_send); + xbt_replay_action_register("Isend", action_Isend); + xbt_replay_action_register("recv", action_recv); + xbt_replay_action_register("Irecv", action_Irecv); + xbt_replay_action_register("wait", action_wait); + xbt_replay_action_register("barrier", action_barrier); + xbt_replay_action_register("bcast", action_bcast); + xbt_replay_action_register("reduce", action_reduce); + xbt_replay_action_register("allReduce",action_allReduce); + xbt_replay_action_register("sleep", action_sleep); + xbt_replay_action_register("compute", action_compute); /* Actually do the simulation using MSG_action_trace_run */ diff --git a/include/msg/msg.h b/include/msg/msg.h index 5280a31f2d..c9c5449410 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -238,10 +238,6 @@ XBT_PUBLIC(MSG_error_t) double timeout); /************************** Action handling **********************************/ -typedef void (*msg_action_fun) (const char *const *args); -XBT_PUBLIC(void) MSG_action_register(const char *action_name, - msg_action_fun function); -XBT_PUBLIC(void) MSG_action_unregister(const char *action_name); MSG_error_t MSG_action_trace_run(char *path); #ifdef MSG_USE_DEPRECATED diff --git a/include/xbt/replay.h b/include/xbt/replay.h new file mode 100644 index 0000000000..2f5d62f993 --- /dev/null +++ b/include/xbt/replay.h @@ -0,0 +1,38 @@ +/* xbt/replay_reader.h -- Tools to parse a replay file */ + +/* Copyright (c) 2010. The SimGrid Team. + * All rights reserved. */ + +/* 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. */ + +#ifndef XBT_REPLAY_H +#define XBT_REPLAY_H +#include "xbt/misc.h" /* SG_BEGIN_DECL */ + +SG_BEGIN_DECL() + +typedef struct s_replay_reader *xbt_replay_reader_t; +typedef void (*action_fun) (const char *const *args); + +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()) */ +FILE *action_fp; + + +xbt_replay_reader_t xbt_replay_reader_new(const char*filename); +const char **xbt_replay_reader_get(xbt_replay_reader_t reader); +void xbt_replay_reader_free(xbt_replay_reader_t *reader); +const char *xbt_replay_reader_position(xbt_replay_reader_t reader); + +int xbt_replay_action_runner(int argc, char *argv[]); + +XBT_PUBLIC(void) xbt_replay_action_register(const char *action_name, + action_fun function); +XBT_PUBLIC(void) xbt_replay_action_unregister(const char *action_name); + +SG_END_DECL() + +#endif /* XBT_REPLAY_H */ diff --git a/include/xbt/replay_trace_reader.h b/include/xbt/replay_trace_reader.h deleted file mode 100644 index f405a73b98..0000000000 --- a/include/xbt/replay_trace_reader.h +++ /dev/null @@ -1,24 +0,0 @@ -/* xbt/replay_trace_reader.h -- Tools to parse a replay file */ - -/* Copyright (c) 2010. The SimGrid Team. - * All rights reserved. */ - -/* 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. */ - -#ifndef XBT_REPLAY_TRACE_READER_H -#define XBT_REPLAY_TRACE_READER_H -#include "xbt/misc.h" /* SG_BEGIN_DECL */ - -SG_BEGIN_DECL() - -typedef struct s_replay_trace_reader *xbt_replay_trace_reader_t; - -xbt_replay_trace_reader_t xbt_replay_trace_reader_new(const char*filename); -const char **xbt_replay_trace_reader_get(xbt_replay_trace_reader_t reader); -void xbt_replay_trace_reader_free(xbt_replay_trace_reader_t *reader); -const char *xbt_replay_trace_reader_position(xbt_replay_trace_reader_t reader); - -SG_END_DECL() - -#endif /* XBT_REPLAY_TRACE_READER_H */ diff --git a/src/msg/msg_actions.c b/src/msg/msg_actions.c index a5424c4a0e..cec0609a81 100644 --- a/src/msg/msg_actions.c +++ b/src/msg/msg_actions.c @@ -9,153 +9,24 @@ #include "msg_private.h" #include "xbt/str.h" #include "xbt/dynar.h" -#include "xbt/replay_trace_reader.h" +#include "xbt/replay.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_action, msg, "MSG actions for trace driven simulation"); -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 const char **action_get_action(char *name); - -/** \ingroup msg_trace_driven - * \brief Registers a function to handle a kind of action - * - * Registers a function to handle a kind of action - * This table is then used by #MSG_action_trace_run - * - * The argument of the function is the line describing the action, splitted on spaces with xbt_str_split_quoted() - * - * \param action_name the reference name of the action. - * \param function prototype given by the type: void...(xbt_dynar_t action) - */ -void MSG_action_register(const char *action_name, msg_action_fun function) -{ - xbt_dict_set(action_funs, action_name, function, NULL); -} - -/** \ingroup msg_trace_driven - * \brief Unregisters a function, which handled a kind of action - * - * \param action_name the reference name of the action. - */ -void MSG_action_unregister(const char *action_name) -{ - xbt_dict_remove(action_funs, action_name); -} - -static int MSG_action_runner(int argc, char *argv[]) -{ - const char **evt; - if (action_fp) { // A unique trace file - - while ((evt = action_get_action(argv[0]))) { - msg_action_fun function = - (msg_action_fun)xbt_dict_get(action_funs, evt[1]); - function(evt); - free(evt); - } - } else { // Should have got my trace file in argument - xbt_assert(argc >= 2, - "No '%s' agent function provided, no simulation-wide trace file provided to MSG_action_trace_run(), " - "and no process-wide trace file provided in deployment file. Aborting.", - argv[0] - ); - xbt_replay_trace_reader_t reader = xbt_replay_trace_reader_new(argv[1]); - while ((evt=xbt_replay_trace_reader_get(reader))) { - if (!strcmp(argv[0],evt[0])) { - msg_action_fun function = - (msg_action_fun)xbt_dict_get(action_funs, evt[1]); - function(evt); - free(evt); - } else { - XBT_WARN("%s: Ignore trace element not for me", - xbt_replay_trace_reader_position(reader)); - } - } - xbt_replay_trace_reader_free(&reader); - } - return 0; -} void _MSG_action_init() { - action_funs = xbt_dict_new_homogeneous(NULL); - action_queues = xbt_dict_new_homogeneous(NULL); - MSG_function_register_default(MSG_action_runner); + _xbt_replay_action_init(); + MSG_function_register_default(xbt_replay_action_runner); } void _MSG_action_exit() { - xbt_dict_free(&action_queues); - xbt_dict_free(&action_funs); + _xbt_replay_action_exit(); } -static const char **action_get_action(char *name) -{ - xbt_dynar_t evt = NULL; - char *evtname = NULL; - - xbt_dynar_t myqueue = xbt_dict_get_or_null(action_queues, name); - if (myqueue == NULL || xbt_dynar_is_empty(myqueue)) { // nothing stored for me. Read the file further - - if (action_fp == NULL) { // File closed now. There's nothing more to read. I'm out of here - goto todo_done; - } - // Read lines until I reach something for me (which breaks in loop body) - // or end of file reached - while (getline(&action_line, &action_len, action_fp) != -1) { - // cleanup and split the string I just read - char *comment = strchr(action_line, '#'); - if (comment != NULL) - *comment = '\0'; - xbt_str_trim(action_line, NULL); - if (action_line[0] == '\0') - continue; - /* we cannot split in place here because we parse&store several lines for - * the colleagues... */ - evt = xbt_str_split_quoted(action_line); - - // if it's for me, I'm done - evtname = xbt_dynar_get_as(evt, 0, char *); - if (!strcmp(name, evtname)) { - return xbt_dynar_to_array(evt); - } else { - // Else, I have to store it for the relevant colleague - xbt_dynar_t otherqueue = - xbt_dict_get_or_null(action_queues, evtname); - if (otherqueue == NULL) { // Damn. Create the queue of that guy - otherqueue = - xbt_dynar_new(sizeof(xbt_dynar_t), xbt_dynar_free_voidp); - xbt_dict_set(action_queues, evtname, otherqueue, NULL); - } - xbt_dynar_push(otherqueue, &evt); - } - } - 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); - return xbt_dynar_to_array(evt); - } - - - // 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); - } - return NULL; -} /** \ingroup msg_trace_driven * \brief A trace loader @@ -170,6 +41,7 @@ MSG_error_t MSG_action_trace_run(char *path) xbt_dynar_t todo; xbt_dict_cursor_t cursor; + action_fp=NULL; if (path) { action_fp = fopen(path, "r"); xbt_assert(action_fp != NULL, "Cannot open %s: %s", path, @@ -187,7 +59,6 @@ MSG_error_t MSG_action_trace_run(char *path) } } - free(action_line); if (path) fclose(action_fp); xbt_dict_free(&action_queues); diff --git a/src/msg/msg_global.c b/src/msg/msg_global.c index 8aa2f6c963..d1a8e5a0bd 100644 --- a/src/msg/msg_global.c +++ b/src/msg/msg_global.c @@ -11,6 +11,7 @@ #include "xbt/log.h" #include "xbt/virtu.h" #include "xbt/ex.h" /* ex_backtrace_display */ +#include "xbt/replay.h" XBT_LOG_NEW_CATEGORY(msg, "All MSG categories"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_kernel, msg, diff --git a/src/xbt/xbt_replay.c b/src/xbt/xbt_replay.c new file mode 100644 index 0000000000..254c8e6246 --- /dev/null +++ b/src/xbt/xbt_replay.c @@ -0,0 +1,213 @@ +/* Copyright (c) 2010. The SimGrid Team. + * All rights reserved. */ + +/* 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 "simgrid_config.h" //For getline, keep that include first + +#include "gras_config.h" +#include +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/str.h" +#include "xbt/replay.h" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(replay,xbt,"Replay trace reader"); + +typedef struct s_replay_reader { + FILE *fp; + char *line; + size_t line_len; + char *position; /* stable storage */ + char *filename; int linenum; +} s_xbt_replay_reader_t; + +static char *action_line = NULL; +static size_t action_len = 0; + + +static const char **action_get_action(char *name); + +xbt_replay_reader_t xbt_replay_reader_new(const char *filename) +{ + xbt_replay_reader_t res = xbt_new0(s_xbt_replay_reader_t,1); + res->fp = fopen(filename, "r"); + xbt_assert(res->fp != NULL, "Cannot open %s: %s", filename, + strerror(errno)); + res->filename = xbt_strdup(filename); + return res; +} + +const char *xbt_replay_reader_position(xbt_replay_reader_t reader) +{ + free(reader->position); + reader->position = bprintf("%s:%d",reader->filename,reader->linenum); + return reader->position; +} + +const char **xbt_replay_reader_get(xbt_replay_reader_t reader) +{ + ssize_t read; + xbt_dynar_t d; + read = getline(&reader->line, &reader->line_len, reader->fp); + //XBT_INFO("got from trace: %s",reader->line); + reader->linenum++; + if (read==-1) + return NULL; /* end of file */ + char *comment = strchr(reader->line, '#'); + if (comment != NULL) + *comment = '\0'; + xbt_str_trim(reader->line, NULL); + if (reader->line[0] == '\0') + return xbt_replay_reader_get(reader); /* Get next line */ + + d=xbt_str_split_quoted_in_place(reader->line); + if (xbt_dynar_is_empty(d)) { + xbt_dynar_free(&d); + return xbt_replay_reader_get(reader); /* Get next line */ + } + return xbt_dynar_to_array(d); +} + +void xbt_replay_reader_free(xbt_replay_reader_t *reader) +{ + free((*reader)->filename); + free((*reader)->position); + fclose((*reader)->fp); + free((*reader)->line); + free(*reader); + *reader=NULL; +} + +/** \ingroup xbt_replay + * \brief Registers a function to handle a kind of action + * + * Registers a function to handle a kind of action + * This table is then used by #xbt_replay_action_run + * + * The argument of the function is the line describing the action, splitted on spaces with xbt_str_split_quoted() + * + * \param action_name the reference name of the action. + * \param function prototype given by the type: void...(xbt_dynar_t action) + */ +void xbt_replay_action_register(const char *action_name, action_fun function) +{ + xbt_dict_set(action_funs, action_name, function, NULL); +} + +/** \ingroup xbt_replay + * \brief Unregisters a function, which handled a kind of action + * + * \param action_name the reference name of the action. + */ +void xbt_replay_action_unregister(const char *action_name) +{ + xbt_dict_remove(action_funs, action_name); +} + +void _xbt_replay_action_init() +{ + action_funs = xbt_dict_new_homogeneous(NULL); + action_queues = xbt_dict_new_homogeneous(NULL); +} + +void _xbt_replay_action_exit() +{ + xbt_dict_free(&action_queues); + xbt_dict_free(&action_funs); + free(action_line); +} + +int xbt_replay_action_runner(int argc, char *argv[]) +{ + const char **evt; + if (action_fp) { // A unique trace file + + while ((evt = action_get_action(argv[0]))) { + action_fun function = + (action_fun)xbt_dict_get(action_funs, evt[1]); + function(evt); + free(evt); + } + } else { // Should have got my trace file in argument + xbt_assert(argc >= 2, + "No '%s' agent function provided, no simulation-wide trace file provided, " + "and no process-wide trace file provided in deployment file. Aborting.", + argv[0] + ); + xbt_replay_reader_t reader = xbt_replay_reader_new(argv[1]); + while ((evt=xbt_replay_reader_get(reader))) { + if (!strcmp(argv[0],evt[0])) { + action_fun function = + (action_fun)xbt_dict_get(action_funs, evt[1]); + function(evt); + free(evt); + } else { + XBT_WARN("%s: Ignore trace element not for me", + xbt_replay_reader_position(reader)); + } + } + xbt_replay_reader_free(&reader); + } + return 0; +} + + +static const char **action_get_action(char *name) +{ + xbt_dynar_t evt = NULL; + char *evtname = NULL; + + xbt_dynar_t myqueue = xbt_dict_get_or_null(action_queues, name); + if (myqueue == NULL || xbt_dynar_is_empty(myqueue)) { // nothing stored for me. Read the file further + + if (action_fp == NULL) { // File closed now. There's nothing more to read. I'm out of here + goto todo_done; + } + // Read lines until I reach something for me (which breaks in loop body) + // or end of file reached + while (getline(&action_line, &action_len, action_fp) != -1) { + // cleanup and split the string I just read + char *comment = strchr(action_line, '#'); + if (comment != NULL) + *comment = '\0'; + xbt_str_trim(action_line, NULL); + if (action_line[0] == '\0') + continue; + /* we cannot split in place here because we parse&store several lines for + * the colleagues... */ + evt = xbt_str_split_quoted(action_line); + + // if it's for me, I'm done + evtname = xbt_dynar_get_as(evt, 0, char *); + if (!strcmp(name, evtname)) { + return xbt_dynar_to_array(evt); + } else { + // Else, I have to store it for the relevant colleague + xbt_dynar_t otherqueue = + xbt_dict_get_or_null(action_queues, evtname); + if (otherqueue == NULL) { // Damn. Create the queue of that guy + otherqueue = + xbt_dynar_new(sizeof(xbt_dynar_t), xbt_dynar_free_voidp); + xbt_dict_set(action_queues, evtname, otherqueue, NULL); + } + xbt_dynar_push(otherqueue, &evt); + } + } + 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); + return xbt_dynar_to_array(evt); + } + + + // 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); + } + return NULL; +} diff --git a/src/xbt/xbt_replay_trace_reader.c b/src/xbt/xbt_replay_trace_reader.c deleted file mode 100644 index 1d34538bab..0000000000 --- a/src/xbt/xbt_replay_trace_reader.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2010. The SimGrid Team. - * All rights reserved. */ - -/* 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 "simgrid_config.h" //For getline, keep that include first - -#include "gras_config.h" -#include -#include "xbt/sysdep.h" -#include "xbt/log.h" -#include "xbt/str.h" -#include "xbt/replay_trace_reader.h" - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(replay,xbt,"Replay trace reader"); - -typedef struct s_replay_trace_reader { - FILE *fp; - char *line; - size_t line_len; - char *position; /* stable storage */ - char *filename; int linenum; -} s_xbt_replay_trace_reader_t; - -xbt_replay_trace_reader_t xbt_replay_trace_reader_new(const char *filename) -{ - xbt_replay_trace_reader_t res = xbt_new0(s_xbt_replay_trace_reader_t,1); - res->fp = fopen(filename, "r"); - xbt_assert(res->fp != NULL, "Cannot open %s: %s", filename, - strerror(errno)); - res->filename = xbt_strdup(filename); - return res; -} - -const char *xbt_replay_trace_reader_position(xbt_replay_trace_reader_t reader) -{ - free(reader->position); - reader->position = bprintf("%s:%d",reader->filename,reader->linenum); - return reader->position; -} - -const char **xbt_replay_trace_reader_get(xbt_replay_trace_reader_t reader) -{ - ssize_t read; - xbt_dynar_t d; - read = getline(&reader->line, &reader->line_len, reader->fp); - //XBT_INFO("got from trace: %s",reader->line); - reader->linenum++; - if (read==-1) - return NULL; /* end of file */ - char *comment = strchr(reader->line, '#'); - if (comment != NULL) - *comment = '\0'; - xbt_str_trim(reader->line, NULL); - if (reader->line[0] == '\0') - return xbt_replay_trace_reader_get(reader); /* Get next line */ - - d=xbt_str_split_quoted_in_place(reader->line); - if (xbt_dynar_is_empty(d)) { - xbt_dynar_free(&d); - return xbt_replay_trace_reader_get(reader); /* Get next line */ - } - return xbt_dynar_to_array(d); -} - -void xbt_replay_trace_reader_free(xbt_replay_trace_reader_t *reader) -{ - free((*reader)->filename); - free((*reader)->position); - fclose((*reader)->fp); - free((*reader)->line); - free(*reader); - *reader=NULL; -}