X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/9b73466ada27682d1729f394549479da83ef4a99..8d000a773b5ebcd411b28c31de68eeddf804e66b:/src/xbt/xbt_replay.c diff --git a/src/xbt/xbt_replay.c b/src/xbt/xbt_replay.c index f539ed1426..b9eef79d37 100644 --- a/src/xbt/xbt_replay.c +++ b/src/xbt/xbt_replay.c @@ -1,16 +1,20 @@ -/* Copyright (c) 2010, 2012-2013. The SimGrid Team. +/* Copyright (c) 2010, 2012-2015. 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 "internal_config.h" -#include +#include "src/internal_config.h" #include "xbt/sysdep.h" #include "xbt/log.h" #include "xbt/str.h" +#include "xbt/file.h" #include "xbt/replay.h" +#include +#include +#include + XBT_LOG_NEW_DEFAULT_SUBCATEGORY(replay,xbt,"Replay trace reader"); typedef struct s_replay_reader { @@ -18,25 +22,41 @@ typedef struct s_replay_reader { char *line; size_t line_len; char *position; /* stable storage */ - char *filename; int linenum; + char *filename; + int linenum; } s_xbt_replay_reader_t; -FILE *action_fp; +FILE *xbt_action_fp; -xbt_dict_t action_funs; -xbt_dict_t action_queues; +xbt_dict_t xbt_action_funs = NULL; +xbt_dict_t xbt_action_queues = NULL; static char *action_line = NULL; static size_t action_len = 0; +int is_replay_active = 0 ; + static char **action_get_action(char *name); +static char *str_tolower (const char *str) +{ + char *ret = xbt_strdup (str); + int i, n = strlen (ret); + for (i = 0; i < n; i++) + ret[i] = tolower (str[i]); + return ret; +} + +int _xbt_replay_is_active(void){ + return is_replay_active; +} + 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)); + if (res->fp == NULL) + xbt_die("Cannot open %s: %s", filename, strerror(errno)); res->filename = xbt_strdup(filename); return res; } @@ -96,7 +116,9 @@ void xbt_replay_reader_free(xbt_replay_reader_t *reader) */ void xbt_replay_action_register(const char *action_name, action_fun function) { - xbt_dict_set(action_funs, action_name, function, NULL); + char* lowername = str_tolower (action_name); + xbt_dict_set(xbt_action_funs, lowername, function, NULL); + xbt_free(lowername); } /** \ingroup XBT_replay @@ -106,25 +128,38 @@ void xbt_replay_action_register(const char *action_name, action_fun function) */ void xbt_replay_action_unregister(const char *action_name) { - xbt_dict_remove(action_funs, action_name); + char* lowername = str_tolower (action_name); + xbt_dict_remove(xbt_action_funs, lowername); + xbt_free(lowername); } -void _xbt_replay_action_init(void) +/** @brief Initializes the replay mechanism, and returns true if (and only if) it was necessary + * + * It returns false if it was already done by another process. + */ +int _xbt_replay_action_init(void) { - action_funs = xbt_dict_new_homogeneous(NULL); - action_queues = xbt_dict_new_homogeneous(NULL); + if (xbt_action_funs) + return 0; + is_replay_active = 1; + xbt_action_funs = xbt_dict_new_homogeneous(NULL); + xbt_action_queues = xbt_dict_new_homogeneous(NULL); + return 1; } void _xbt_replay_action_exit(void) { - xbt_dict_free(&action_queues); - xbt_dict_free(&action_funs); + xbt_dict_free(&xbt_action_queues); + xbt_dict_free(&xbt_action_funs); free(action_line); + xbt_action_queues = NULL; + xbt_action_funs = NULL; + action_line = NULL; } /** * \ingroup XBT_replay - * \brief TODO + * \brief function used internally to actually run the replay * \param argc argc . * \param argv argv @@ -132,12 +167,22 @@ void _xbt_replay_action_exit(void) int xbt_replay_action_runner(int argc, char *argv[]) { int i; - if (action_fp) { // A unique trace file + xbt_ex_t e; + if (xbt_action_fp) { // A unique trace file char **evt; while ((evt = action_get_action(argv[0]))) { + char* lowername = str_tolower (evt[1]); action_fun function = - (action_fun)xbt_dict_get(action_funs, evt[1]); - function((const char **)evt); + (action_fun)xbt_dict_get(xbt_action_funs, lowername); + xbt_free(lowername); + TRY{ + function((const char **)evt); + } + CATCH(e) { + free(evt); + xbt_die("Replay error :\n %s" + , e.msg); + } for (i=0;evt[i]!= NULL;i++) free(evt[i]); free(evt); @@ -152,8 +197,17 @@ int xbt_replay_action_runner(int argc, char *argv[]) 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); + char* lowername = str_tolower (evt[1]); + action_fun function = (action_fun)xbt_dict_get(xbt_action_funs, lowername); + xbt_free(lowername); + TRY{ + function(evt); + } + CATCH(e) { + free(evt); + xbt_die("Replay error on line %d of file %s :\n %s" + , reader->linenum,reader->filename, e.msg); + } } else { XBT_WARN("%s: Ignore trace element not for me", xbt_replay_reader_position(reader)); @@ -171,15 +225,15 @@ static 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); + xbt_dynar_t myqueue = xbt_dict_get_or_null(xbt_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 + if (xbt_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 (xbt_getline(&action_line, &action_len, action_fp) != -1) { + while (xbt_getline(&action_line, &action_len, xbt_action_fp) != -1) { // cleanup and split the string I just read char *comment = strchr(action_line, '#'); if (comment != NULL) @@ -193,16 +247,16 @@ static char **action_get_action(char *name) // if it's for me, I'm done evtname = xbt_dynar_get_as(evt, 0, char *); - if (!strcmp(name, evtname)) { + if (!strcasecmp(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); + xbt_dict_get_or_null(xbt_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_dict_set(xbt_action_queues, evtname, otherqueue, NULL); } xbt_dynar_push(otherqueue, &evt); } @@ -220,7 +274,7 @@ static char **action_get_action(char *name) todo_done: if (myqueue != NULL) { xbt_dynar_free(&myqueue); - xbt_dict_remove(action_queues, name); + xbt_dict_remove(xbt_action_queues, name); } return NULL; }