From: alegrand Date: Thu, 1 Apr 2010 11:22:39 +0000 (+0000) Subject: Huge import with Lucas tracing modifications. X-Git-Tag: SVN~331 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/1b30f00857843f1cee60814ed519ff82e8ef4787 Huge import with Lucas tracing modifications. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7409 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/README.tracing b/README.tracing new file mode 100644 index 0000000000..a4dabb063b --- /dev/null +++ b/README.tracing @@ -0,0 +1,124 @@ + ======= +instrumented SimGrid + ======= + +In order to trace the simulators created with the SimGrid toolkit and based on +the MSG interface, you have to enable the instrumentation mechanisms with this +option to the configure command (in addition to other options you may be already +using): + +$ ./configure --enable-tracing + +By doing that, you will have access to a set of tracing functions that are +described below. You can keep the calls for these functions in your code even if +SimGrid was compiled without this configuration option. + +Mandatory functions: +========= + +int TRACE_start(const char *filename); + + This is the first function to be called. It receives a single argument + as parameter that contains the name of the file that will hold the trace + in the end of the simulation. It returns 1 if everything was properly + initialized, 0 otherwise. All trace functions called before TRACE_start + do nothing. By default, the instrumentation will trace the platform + behavior (host and link utilization). + +int TRACE_end (void); + + This is the last function to be called. It closes the trace file and + disable the tracing of the simulation. All trace functions called after + TRACE_end do nothing. + +void TRACE_category (const char *category); + + This function should be used to define a user category. The category can + be used to differentiate the tasks that are created during the + simulation (for example, tasks from server1, server2, ...). All resource + utilization (host power and link bandwidth) will be classified according + to the task category. Tasks that do not belong to a category are not + traced. + +void TRACE_msg_set_task_category (m_task_t task, const char *category); + + This function should be called after the creation of a task, to define + the category of that task. Only tasks with a category are traced when + TRACE_TASK is used as mask. + + +Optional functions (that can be used if necessary): +======== + +void TRACE_set_mask (int mask); + + This function can be used to control what is traced during the + simulation. The user has four masks that can be used: + - TRACE_PLATFORM - trace resource (host,link) utilization + - TRACE_PROCESS - trace process behavior (suspend, execute) + - TRACE_TASK - trace task behavior (created, execute, comm) + - NO_TRACE - can be used to disable the traces for a moment + The platform mask must be present in order to trace processes or tasks. + +void TRACE_start_with_mask (const char *filename, int mask); + + This function can be used to start the tracing with a different mask + and replaces the use of TRACE_start. The initial mask defined with this + function cannot be "extended" later with the TRACE_set_mask function. + This means that if TRACE_start_with_mask is called with the mask + (TRACE_PLATFORM|TRACE_TASK), the user cannot set the mask later to + (TRACE_PLATFORM|TRACE_PROCESS), for instance. The best combinations of + mask for tracing the current instrumentation are: + - (TRACE_PLATFORM|TRACE_TASK) or + Tasks are grouped by hosts. + - (TRACE_PLATFORM|TRACE_PROCESS) or + Processes are grouped by hosts. + - (TRACE_PLATFORM|TRACE_PROCESS|TRACE_TASK) + Processes are grouped by hosts, tasks by processes. + Only tasks and processes belonging to a category are traced. + +void TRACE_host_variable_declare (const char *variable); + + Declare a user variable that will be associated to the host. + +void TRACE_host_variable_set (const char *variable, double value); +void TRACE_host_variable_add (const char *variable, double value); +void TRACE_host_variable_sub (const char *variable, double value); + + Set the value of a given user variable. It is important to remind that + the value of this variable is always associated to the host. The host + that will be used when these functions are called is the one returned by + the function MSG_host_self(). + +void TRACE_define_type (const char *type, + const char *parent_type, + int final); + + This function allows the definition of a type hierarchy that can be used + to create different categories. This root of the type hierarchy is + defined as "0", so the first level of type must be child of the type + "0". The boolean parameter final (1 or 0) indicates if the categories + of a given type will be used to mark MSG tasks or not. This is used to + differentiate types that are defined only to group other types. + +void TRACE_create_category (const char *category, + const char *type, + const char *parent_category); + + This functions allows the creation of categories and a hierarchy of + categories. Each category created with this function (first parameter) + must belong to a given type previously defined with the + TRACE_define_type. It has to be also a child of a previously created + category, which is indicated by the parent_category. The user can + created categories that are child of "0" if the type of this newly + created category is also child of the type "0" (as defined by + TRACE_define_type). + +void TRACE_msg_set_process_category (m_process_t process, const char *category); + + This function can be used to define the category of a process. The same + categories declared for tasks can be used here. After setting the + category of a process and enabling the mask TRACE_PROCESS, the + instrumentation will trace the process behavior, such as the states for + execution, suspend, and so on. Only processes with categories are traced + when TRACE_PROCESS is enabled. diff --git a/buildtools/Cmake/src/CMakeCompleteInFiles.txt b/buildtools/Cmake/src/CMakeCompleteInFiles.txt index d971ebd937..95dd3920f5 100644 --- a/buildtools/Cmake/src/CMakeCompleteInFiles.txt +++ b/buildtools/Cmake/src/CMakeCompleteInFiles.txt @@ -83,6 +83,10 @@ if(NOT disable_ruby) endif(RUBY_INCLUDE_PATH) endif(NOT disable_ruby) +if(tracing) + SET(HAVE_TRACING 1) +endif(tracing) + #-------------------------------------------------------------------------------------------------- ### Initialize of CONTEXT JAVA if(disable_java) diff --git a/buildtools/Cmake/src/CMakeDefinePackages.txt b/buildtools/Cmake/src/CMakeDefinePackages.txt index 1e1ce7cd03..800d4f68bb 100644 --- a/buildtools/Cmake/src/CMakeDefinePackages.txt +++ b/buildtools/Cmake/src/CMakeDefinePackages.txt @@ -291,6 +291,17 @@ set(LUA_SRC ${PROJECT_DIRECTORY}/src/bindings/lua/simgrid_lua.c ) +set(TRACING_SRC + ${PROJECT_DIRECTORY}/src/instr/interface.c + ${PROJECT_DIRECTORY}/src/instr/general.c + ${PROJECT_DIRECTORY}/src/instr/paje.c + ${PROJECT_DIRECTORY}/src/instr/msg_task_instr.c + ${PROJECT_DIRECTORY}/src/instr/msg_process_instr.c + ${PROJECT_DIRECTORY}/src/instr/smx_instr.c + ${PROJECT_DIRECTORY}/src/instr/surf_instr.c + ${PROJECT_DIRECTORY}/src/instr/variables_instr.c +) + set(RUBY_SRC ${PROJECT_DIRECTORY}/src/simix/smx_context_ruby.c ${PROJECT_DIRECTORY}/src/bindings/ruby/rb_msg_process.c @@ -348,6 +359,7 @@ set(simgrid_sources ${GTNETS_USED} ${SIMIX_SRC} ${MSG_SRC} + ${TRACING_SRC} ${SIMDAG_SRC} ${GRAS_COMMON_SRC} ${GRAS_SG_SRC} diff --git a/buildtools/Cmake/src/CMakeOption.txt b/buildtools/Cmake/src/CMakeOption.txt index cf01d9d2d7..bc423e39b9 100644 --- a/buildtools/Cmake/src/CMakeOption.txt +++ b/buildtools/Cmake/src/CMakeOption.txt @@ -19,6 +19,7 @@ option(enable_maintainer_mode "Permit to make flex and flexml files." off) option(enable_coverage "Enable coverage." off) option(enable_memcheck "Enable memcheck." off) option(supernovae "Supernovae mode." off) +option(tracing "Tracing mode." off) option(print_message "Enable print message during config." off) mark_as_advanced(LUA_LIB_PATH_1) diff --git a/buildtools/Cmake/src/c_gras_config.h.in b/buildtools/Cmake/src/c_gras_config.h.in index 5ad7108ebb..60a4b2d6e8 100644 --- a/buildtools/Cmake/src/c_gras_config.h.in +++ b/buildtools/Cmake/src/c_gras_config.h.in @@ -236,6 +236,9 @@ /* Version number of package */ #cmakedefine VERSION @VERSION@ +/* Tracing SimGrid */ +#cmakedefine HAVE_TRACING @HAVE_TRACING@ + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/configure.ac b/configure.ac index 2f9d91fe70..b0528a236f 100644 --- a/configure.ac +++ b/configure.ac @@ -378,6 +378,18 @@ then fi SG_COMPILE_FLAGS +## +## Support for tracing instrumentation +## +AC_CONFIG_HEADERS([include/instr/config.h]) +AC_ARG_ENABLE(tracing, + AS_HELP_STRING([--enable-tracing],[Activate the instrumentation so SimGrid can be traced to be visualized]), + [tracing=$enableval], + [tracing=no]) +if test x$tracing = xyes ; then + AC_DEFINE([HAVE_TRACING],[1], [defines whether instrumentation must be compiled or not]) +fi + ## ## Support for the supernovae compilation mode ## diff --git a/examples/msg/gtnets/gtnets.c b/examples/msg/gtnets/gtnets.c index fe661afa12..8e6c295eab 100644 --- a/examples/msg/gtnets/gtnets.c +++ b/examples/msg/gtnets/gtnets.c @@ -53,11 +53,14 @@ int master(int argc, char *argv[]) sprintf(id_alias, "%d", id); slavenames[id] = slavename; + TRACE_category (slavename); + masternames[id] = MSG_host_get_name(MSG_host_self()); { /* Task creation. */ char sprintf_buffer[64] = "Task_0"; todo = MSG_task_create(sprintf_buffer, 0, task_comm_size, NULL); + TRACE_msg_set_task_category(todo,slavename); //keep track of running tasks gl_task_array[id] = todo; gl_data_size[id] = task_comm_size; @@ -123,7 +126,7 @@ int slave(int argc, char *argv[]) slavenames[id], remaining); } } - exit(0); + //exit(0); } for (id = 0; id < NTASKS; id++) { @@ -163,6 +166,8 @@ int main(int argc, char *argv[]) MSG_error_t res = MSG_OK; bool_printed = 0; + TRACE_start ("z_gtnets.trace"); + MSG_global_init(&argc, argv); if (argc < 3) { printf("Usage: %s platform_file deployment_file\n", argv[0]); @@ -172,6 +177,8 @@ int main(int argc, char *argv[]) MSG_clean(); + TRACE_end (); + if (res == MSG_OK) return 0; else diff --git a/examples/msg/masterslave/masterslave_forwarder.c b/examples/msg/masterslave/masterslave_forwarder.c index c1eb978451..50807a036c 100644 --- a/examples/msg/masterslave/masterslave_forwarder.c +++ b/examples/msg/masterslave/masterslave_forwarder.c @@ -37,6 +37,7 @@ int master(int argc, char *argv[]) double task_comp_size = 0; double task_comm_size = 0; + TRACE_host_variable_set ("is_master", 1); int i; @@ -56,6 +57,8 @@ int master(int argc, char *argv[]) sprintf(sprintf_buffer, "Task_%d", i); todo[i] = MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, NULL); + TRACE_host_variable_set ("task_creation", i); + TRACE_msg_set_task_category (todo[i], "compute"); } } @@ -88,9 +91,11 @@ int master(int argc, char *argv[]) INFO0 ("All tasks have been dispatched. Let's tell everybody the computation is over."); - for (i = 0; i < slaves_count; i++) - MSG_task_put(MSG_task_create("finalize", 0, 0, FINALIZE), - slaves[i], PORT_22); + for (i = 0; i < slaves_count; i++){ + m_task_t finalize=MSG_task_create("finalize", 0, 0, FINALIZE); + TRACE_msg_set_task_category(finalize,"finalize"); + MSG_task_put(finalize, slaves[i], PORT_22); + } INFO0("Goodbye now!"); free(slaves); @@ -102,6 +107,7 @@ int master(int argc, char *argv[]) int slave(int argc, char *argv[]) { m_task_t task = NULL; + TRACE_host_variable_set ("is_slave", 1); int res; while (1) { res = MSG_task_get(&(task), PORT_22); @@ -114,6 +120,7 @@ int slave(int argc, char *argv[]) } INFO1("Processing \"%s\"", MSG_task_get_name(task)); + TRACE_host_variable_add ("task_computation", MSG_task_get_compute_duration(task)); MSG_task_execute(task); INFO1("\"%s\" done", MSG_task_get_name(task)); MSG_task_destroy(task); @@ -202,6 +209,14 @@ int main(int argc, char *argv[]) { MSG_error_t res = MSG_OK; + TRACE_start ("zmsg_test.trace"); + TRACE_host_variable_declare ("is_slave"); + TRACE_host_variable_declare ("is_master"); + TRACE_host_variable_declare ("task_creation"); + TRACE_host_variable_declare ("task_computation"); + TRACE_category ("compute"); + TRACE_category ("finalize"); + MSG_global_init(&argc, argv); if (argc < 3) { printf("Usage: %s platform_file deployment_file\n", argv[0]); @@ -211,6 +226,8 @@ int main(int argc, char *argv[]) res = test_all(argv[1], argv[2]); MSG_clean(); + TRACE_end (); + if (res == MSG_OK) return 0; else diff --git a/examples/msg/migration/migration.c b/examples/msg/migration/migration.c index 04186bed6a..44de664709 100644 --- a/examples/msg/migration/migration.c +++ b/examples/msg/migration/migration.c @@ -16,6 +16,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, /** The guy we will move from host to host. It move alone and then is moved by policeman back */ static int emigrant(int argc, char *argv[]) { + TRACE_msg_set_process_category (MSG_process_self(), "emigrant"); m_task_t task; INFO0 ("I'll look for a new job on another machine where the grass is greener."); @@ -24,8 +25,11 @@ static int emigrant(int argc, char *argv[]) task = MSG_task_create("job", 98095000, 0, NULL); MSG_task_execute(task); MSG_task_destroy(task); + MSG_process_sleep (2); INFO0("Moving back home after work"); MSG_process_change_host(MSG_get_host_by_name("Jacquelin")); + MSG_process_change_host(MSG_get_host_by_name("Boivin")); + MSG_process_sleep (4); INFO0("Uh, nothing to do here. Stopping now"); return 0; } /* end_of_emigrant */ @@ -45,6 +49,9 @@ int main(int argc, char *argv[]) { MSG_error_t res = MSG_OK; + TRACE_start_with_mask ("zmsg_test.trace", TRACE_PLATFORM|TRACE_PROCESS); + TRACE_category ("emigrant"); + /* Argument checking */ MSG_global_init(&argc, argv); if (argc < 3) { @@ -67,6 +74,8 @@ int main(int argc, char *argv[]) if (res == MSG_OK) res = MSG_clean(); + TRACE_end (); + if (res == MSG_OK) return 0; else diff --git a/examples/msg/small_platform_with_routers.xml b/examples/msg/small_platform_with_routers.xml new file mode 100755 index 0000000000..45f186fd77 --- /dev/null +++ b/examples/msg/small_platform_with_routers.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/Makefile.am b/include/Makefile.am index 0256a4b5aa..06f26d1a09 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -51,7 +51,10 @@ nobase_include_HEADERS = \ gras/messages.h gras/timer.h \ \ amok/peermanagement.h \ - amok/bandwidth.h + amok/bandwidth.h \ + \ + instr/instr.h \ + instr/config.h surf/simgrid_dtd.h: $(MAKE) -C ../src ../include/surf/simgrid_dtd.h diff --git a/include/instr/config.h b/include/instr/config.h new file mode 100644 index 0000000000..759579ec9f --- /dev/null +++ b/include/instr/config.h @@ -0,0 +1,3 @@ +/* include/instr/config.h. Generated from config.h.in by configure. */ +/* defines whether instrumentation must be compiled or not */ +#define HAVE_TRACING 1 diff --git a/include/instr/config.h.in b/include/instr/config.h.in new file mode 100644 index 0000000000..f2f159d05c --- /dev/null +++ b/include/instr/config.h.in @@ -0,0 +1,2 @@ +/* defines whether instrumentation must be compiled or not */ +#undef HAVE_TRACING diff --git a/include/instr/instr.h b/include/instr/instr.h new file mode 100644 index 0000000000..17715d2b68 --- /dev/null +++ b/include/instr/instr.h @@ -0,0 +1,121 @@ +/* + * instr.h + * + * Created on: Nov 23, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#ifndef INSTR_H_ +#define INSTR_H_ + +#include "instr/config.h" + +#ifdef HAVE_TRACING + +#define NO_TRACE 0 +#define TRACE_PLATFORM 1 +#define TRACE_PROCESS 2 +#define TRACE_TASK 4 + +#include "xbt.h" +#include "msg/msg.h" + +/* Trace error codes (used in exceptions) */ +#define TRACE_ERROR_COMPLEX_ROUTES 100 +#define TRACE_ERROR_TYPE_NOT_DEFINED 200 +#define TRACE_ERROR_TYPE_ALREADY_DEFINED 201 +#define TRACE_ERROR_CATEGORY_NOT_DEFINED 300 +#define TRACE_ERROR_CATEGORY_ALREADY_DEFINED 301 +#define TRACE_ERROR_MASK 400 +#define TRACE_ERROR_FILE_OPEN 401 + +XBT_PUBLIC(int) TRACE_start_with_mask (const char *filename, int mask); +XBT_PUBLIC(int) TRACE_end (void); +XBT_PUBLIC(void) TRACE_category (const char *category); +XBT_PUBLIC(void) TRACE_define_type (const char *type, const char *parent_type, int final); +XBT_PUBLIC(void) TRACE_create_category (const char *category, const char *type, const char *parent_category); +XBT_PUBLIC(void) TRACE_msg_set_task_category (m_task_t task, const char *category); +XBT_PUBLIC(void) TRACE_msg_set_process_category (m_process_t process, const char *category); +XBT_PUBLIC(void) TRACE_set_mask (int mask); +XBT_PUBLIC(void) __TRACE_host_variable (double time, const char *variable, double value, const char *what); +XBT_PUBLIC(void) __TRACE_link_variable (double time, const char *src, const char *dst, const char *variable, double value, const char *what); + +#define TRACE_start(filename) TRACE_start_with_mask(filename,TRACE_PLATFORM) + +#define TRACE_host_variable_declare(var) \ + __TRACE_host_variable(0,var,0,"declare"); + +#define TRACE_host_variable_set_with_time(time,var,value) \ + __TRACE_host_variable(time,var,value,"set"); + +#define TRACE_host_variable_add_with_time(time,var,value) \ + __TRACE_host_variable(time,var,value,"add"); + +#define TRACE_host_variable_sub_with_time(time,var,value) \ + __TRACE_host_variable(time,var,value,"sub"); + +#define TRACE_host_variable_set(var,value) \ + __TRACE_host_variable(MSG_get_clock(),var,value,"set"); + +#define TRACE_host_variable_add(var,value) \ + __TRACE_host_variable(MSG_get_clock(),var,value,"add"); + +#define TRACE_host_variable_sub(var,value) \ + __TRACE_host_variable(MSG_get_clock(),var,value,"sub"); + +#define TRACE_link_variable_declare(var) \ + __TRACE_link_variable(0,NULL,NULL,var,0,"declare"); + +#define TRACE_link_variable_set_with_time(time,src,dst,var,value) \ + __TRACE_link_variable(time,src,dst,var,value,"set"); + +#define TRACE_link_variable_add_with_time(time,src,dst,var,value) \ + __TRACE_link_variable(time,src,dst,var,value,"add"); + +#define TRACE_link_variable_sub_with_time(time,src,dst,var,value) \ + __TRACE_link_variable(time,src,dst,var,value,"sub"); + +#define TRACE_link_variable_set(src,dst,var,value) \ + __TRACE_link_variable(MSG_get_clock(),src,dst,var,value,"set"); + +#define TRACE_link_variable_add(src,dst,var,value) \ + __TRACE_link_variable(MSG_get_clock(),src,dst,var,value,"add"); + +#define TRACE_link_variable_sub(src,dst,var,value) \ + __TRACE_link_variable(MSG_get_clock(),src,dst,var,value,"sub"); + +#else /* HAVE_TRACING */ + +#define TRACE_start(filename) +#define TRACE_start_with_mask(filename,mask) +#define TRACE_end() +#define TRACE_category(cat) +#define TRACE_define_type(cat,supercat,final) +#define TRACE_create_category(inst,cat) +#define TRACE_msg_set_task_category(task,cat) +#define TRACE_msg_set_process_category(proc,cat) +#define TRACE_set_mask(mask) + +#define TRACE_host_variable_declare(var) +#define TRACE_host_variable_set_with_time(time,var,value) +#define TRACE_host_variable_add_with_time(time,var,value) +#define TRACE_host_variable_sub_with_time(time,var,value) +#define TRACE_host_variable_set(var,value) +#define TRACE_host_variable_add(var,value) +#define TRACE_host_variable_sub(var,value) +#define TRACE_link_variable_declare(var) +#define TRACE_link_variable_set_with_time(time,src,dst,var,value) +#define TRACE_link_variable_add_with_time(time,src,dst,var,value) +#define TRACE_link_variable_sub_with_time(time,src,dst,var,value) +#define TRACE_link_variable_set(src,dst,var,value) +#define TRACE_link_variable_add(src,dst,var,value) +#define TRACE_link_variable_sub(src,dst,var,value) + +#endif /* HAVE_TRACING */ + +#endif /* INSTR_H_ */ diff --git a/include/msg/datatypes.h b/include/msg/datatypes.h index 20a35d68f8..0446f96488 100644 --- a/include/msg/datatypes.h +++ b/include/msg/datatypes.h @@ -8,6 +8,7 @@ #ifndef MSG_DATATYPE_H #define MSG_DATATYPE_H #include "xbt/misc.h" +#include "instr/config.h" SG_BEGIN_DECL() @@ -45,6 +46,10 @@ SG_BEGIN_DECL() char *name; /**< @brief task name if any */ simdata_task_t simdata; /**< @brief simulator data */ void *data; /**< @brief user data */ +#ifdef HAVE_TRACING + long long int counter; /* task unique identifier for instrumentation */ + char *category; /* task category for instrumentation */ +#endif } s_m_task_t; /** @brief Task datatype @ingroup m_datatypes_management @@ -74,6 +79,7 @@ SG_BEGIN_DECL() simdata_process_t simdata; /**< @brief simulator data */ void *data; /**< @brief user data */ + char *category; /* process category for instrumentation */ } s_m_process_t; /** @} */ /** @brief Agent datatype diff --git a/include/msg/msg.h b/include/msg/msg.h index e8d581f8eb..12465e6b3d 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -209,5 +209,7 @@ XBT_PUBLIC(void) MSG_action_unregister(const char *action_name); #endif +#include "instr/instr.h" + SG_END_DECL() #endif diff --git a/include/xbt/ex.h b/include/xbt/ex.h index af1c0a3955..619d16beac 100644 --- a/include/xbt/ex.h +++ b/include/xbt/ex.h @@ -238,7 +238,8 @@ typedef enum { network_error, /**< error while sending/receiving data */ timeout_error, /**< not quick enough, dude */ thread_error, /**< error while [un]locking */ - host_error /**< host failed */ + host_error, /**< host failed */ + tracing_error /**< error during the simulation tracing */ } xbt_errcat_t; XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat); diff --git a/include/xbt/str.h b/include/xbt/str.h index 78786a9265..9e807c83bc 100644 --- a/include/xbt/str.h +++ b/include/xbt/str.h @@ -48,6 +48,7 @@ XBT_PUBLIC(char *) xbt_str_varsubst(char *str, xbt_dict_t patterns); XBT_PUBLIC(void) xbt_str_strip_spaces(char *); XBT_PUBLIC(char *) xbt_str_diff(char *a, char *b); +XBT_PUBLIC(long) getline(char **lineptr, size_t * n, FILE * stream); XBT_PUBLIC(char*)xbt_str_from_file(FILE *file); diff --git a/src/Makefile.am b/src/Makefile.am index 05cc755c60..120033faf5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -214,7 +214,17 @@ SIMIX_SRC= \ simix/smx_synchro.c \ simix/smx_network.c \ simix/smx_context_base.c - + +TRACING_SRC=\ + instr/interface.c \ + instr/general.c \ + instr/paje.c \ + instr/msg_task_instr.c \ + instr/msg_process_instr.c \ + instr/smx_instr.c \ + instr/surf_instr.c \ + instr/variables_instr.c + if CONTEXT_THREADS SURF_SRC += xbt/xbt_os_thread.c simix/smx_context_thread.c EXTRA_DIST += simix/smx_context_sysv.c @@ -339,7 +349,8 @@ lib_LTLIBRARIES= libsimgrid.la libgras.la libsmpi.la gras_sources=$(XBT_SRC) $(GRAS_COMMON_SRC) $(GRAS_RL_SRC) $(AMOK_SRC) simgrid_sources=$(XBT_SRC) $(SURF_SRC) $(GTNETS_USED) \ $(SIMIX_SRC) $(MSG_SRC) $(SIMDAG_SRC) \ - $(GRAS_COMMON_SRC) $(GRAS_SG_SRC) $(AMOK_SRC) + $(GRAS_COMMON_SRC) $(GRAS_SG_SRC) $(AMOK_SRC) \ + $(TRACING_SRC) libgras_la_LDFLAGS = -no-undefined $(VERSION_INFO) @GRAS_DEP@ @LD_DYNAMIC_FLAGS@ -lm @@ -388,7 +399,7 @@ simgrid.jar: $(JMSG_JAVA_SRC) [ -e .classes/surf ] || mkdir .classes/surf $(JAR) cvf simgrid.jar -C .classes . else -EXTRA_DIST+=$(JMSG_C_SRC) $(JMSG_JAVA_SRC) $(MSG_SRC) +EXTRA_DIST+=$(JMSG_C_SRC) $(JMSG_JAVA_SRC) $(MSG_SRC) $(TRACING_SRC) endif LUA_SRC= simix/smx_context_lua.c bindings/lua/simgrid_lua.c #bindings/lua/Msglua.c diff --git a/src/instr/general.c b/src/instr/general.c new file mode 100644 index 0000000000..d7f002b768 --- /dev/null +++ b/src/instr/general.c @@ -0,0 +1,101 @@ +/* + * general.c + * + * Created on: Nov 23, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + + +#ifdef HAVE_TRACING + +xbt_dict_t created_containers = NULL; + +char *TRACE_paje_msg_container (m_task_t task, char *host, char *output, int len) +{ + if (output){ + snprintf (output, len, "msg-%p-%s-%lld", task, host, task->counter); + return output; + }else{ + return NULL; + } +} + +char *TRACE_paje_smx_container (smx_action_t action, int seqnumber, char *host, char *output, int len) +{ + if (output){ + snprintf (output, len, "smx-%p-%d", action, seqnumber); + return output; + }else{ + return NULL; + } +} + +char *TRACE_paje_surf_container (void *action, int seqnumber, char *output, int len) +{ + if (output){ + snprintf (output, len, "surf-%p-%d", action, seqnumber); + return output; + }else{ + return NULL; + } +} + +char *TRACE_host_container (m_host_t host, char *output, int len) +{ + if (output){ + snprintf (output, len, "%s", MSG_host_get_name(host)); + return output; + }else{ + return NULL; + } +} + +char *TRACE_task_container (m_task_t task, char *output, int len) +{ + if (output){ + snprintf (output, len, "%p-%lld", task, task->counter); + return output; + }else{ + return NULL; + } +} + +char *TRACE_process_container (m_process_t process, char *output, int len) +{ + if (output){ + snprintf (output, len, "%s-%p", MSG_process_get_name(process), process); + return output; + }else{ + return NULL; + } +} + +char *TRACE_process_alias_container (m_process_t process, m_host_t host, char *output, int len) +{ + if (output){ + snprintf (output, len, "%p-%p", process, host); + return output; + }else{ + return NULL; + } +} + +char *TRACE_task_alias_container (m_task_t task, m_process_t process, m_host_t host, char *output, int len) +{ + if (output){ + snprintf (output, len, "%p-%lld-%p-%p", task, task->counter, process, host); + return output; + }else{ + return NULL; + } +} + +#endif diff --git a/src/instr/interface.c b/src/instr/interface.c new file mode 100644 index 0000000000..78092e67bf --- /dev/null +++ b/src/instr/interface.c @@ -0,0 +1,178 @@ +/* + * interface.c + * + * Created on: Nov 23, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + + +#ifdef HAVE_TRACING + +XBT_LOG_NEW_DEFAULT_CATEGORY(tracing,"Tracing Surf"); + +extern xbt_dict_t created_containers; /* declared in general.c */ +static xbt_dict_t defined_types; +static xbt_dict_t created_categories; + +int trace_mask; + +/** + * \brief Initialization of tracing. + * + * Function to be called at first when tracing a simulation + * + * \param name of the file that will contain the traces + * \param mask to take into account during trace + * \return 1 if everything is ok, 0 otherwise + */ +int TRACE_start_with_mask(const char *filename, int mask) { + if (IS_TRACING) { /* what? trace is already active... ignore.. */ + return 0; + } + + FILE *file = fopen(filename, "w"); + if (!file) { + THROW1 (tracing_error, TRACE_ERROR_FILE_OPEN, + "Tracefile %s could not be opened for writing.", filename); + } else { + TRACE_paje_start (file); + } + TRACE_paje_create_header(); + + /* default trace is to trace only the platform */ + trace_mask = mask; + + //check if options are correct + if (IS_TRACING_TASKS){ + if (!IS_TRACING_PROCESSES){ + TRACE_end(); + THROW0 (tracing_error, TRACE_ERROR_MASK, + "TRACE_PROCESS must be enabled if TRACE_TASK is used"); + } + } + + if (IS_TRACING_PROCESSES|IS_TRACING_TASKS){ + if (!IS_TRACING_PLATFORM){ + TRACE_end(); + THROW0 (tracing_error, TRACE_ERROR_MASK, + "TRACE_PLATFORM must be enabled if TRACE_PROCESS or TRACE_TASK is used"); + } + } + + //defining platform hierarchy + if (IS_TRACING_PLATFORM) pajeDefineContainerType("PLATFORM", "0", "platform"); + if (IS_TRACING_PLATFORM) pajeDefineContainerType("HOST", "PLATFORM", "HOST"); + if (IS_TRACING_PLATFORM) pajeDefineVariableType ("power", "HOST", "power"); + if (IS_TRACING_PLATFORM) pajeDefineContainerType("LINK", "PLATFORM", "LINK"); + if (IS_TRACING_PLATFORM) pajeDefineVariableType ("bandwidth", "LINK", "bandwidth"); + if (IS_TRACING_PLATFORM) pajeDefineVariableType ("latency", "LINK", "latency"); + + if (IS_TRACING_PROCESSES) pajeDefineContainerType("PROCESS", "HOST", "PROCESS"); + if (IS_TRACING_PROCESSES) pajeDefineStateType("presence", "PROCESS", "presence"); + + if (IS_TRACING_PROCESSES){ + if (IS_TRACING_TASKS) pajeDefineContainerType("TASK", "PROCESS", "TASK"); + }else{ + if (IS_TRACING_TASKS) pajeDefineContainerType("TASK", "HOST", "TASK"); + } + + if (IS_TRACING_PLATFORM) pajeCreateContainer(MSG_get_clock(), "platform", "PLATFORM", "0", "simgrid-platform"); + + created_containers = xbt_dict_new(); + defined_types = xbt_dict_new(); + created_categories = xbt_dict_new(); + __TRACE_msg_init(); + __TRACE_surf_init(); + __TRACE_msg_process_init (); + + return 1; +} + +int TRACE_end() { + if (!IS_TRACING) return 0; + __TRACE_surf_finalize(); + FILE *file = TRACE_paje_end(); + fclose (file); + return 1; +} + +void TRACE_category (const char *category) +{ + if (!IS_TRACING) return; + static int first_time = 1; + if (first_time){ + TRACE_define_type ("user_type", "0", 1); + first_time = 0; + } + TRACE_create_category (category, "user_type", "0"); +} + +void TRACE_define_type (const char *type, + const char *parent_type, int final) { + if (!IS_TRACING) return; + + //check if type is already defined + if (xbt_dict_get_or_null (defined_types, type)){ + THROW1 (tracing_error, TRACE_ERROR_TYPE_ALREADY_DEFINED, "Type %s is already defined", type); + } + //check if parent_type is already defined + if (strcmp(parent_type, "0") && !xbt_dict_get_or_null (defined_types, parent_type)) { + THROW1 (tracing_error, TRACE_ERROR_TYPE_NOT_DEFINED, "Type (used as parent) %s is not defined", parent_type); + } + + pajeDefineContainerType(type, parent_type, type); + if (final) { + //for m_process_t + if (IS_TRACING_PROCESSES) pajeDefineContainerType ("process", type, "process"); + if (IS_TRACING_PROCESSES) pajeDefineStateType ("process-state", "process", "process-state"); + + if (IS_TRACING_TASKS) pajeDefineContainerType ("task", type, "task"); + if (IS_TRACING_TASKS) pajeDefineStateType ("task-state", "task", "task-state"); + } + xbt_dict_set (defined_types, type, xbt_strdup("1"), xbt_free); +} + +void TRACE_create_category (const char *category, + const char *type, const char *parent_category) +{ + if (!IS_TRACING) return; + + //check if type is defined + if (!xbt_dict_get_or_null (defined_types, type)) { + THROW1 (tracing_error, TRACE_ERROR_TYPE_NOT_DEFINED, "Type %s is not defined", type); + } + //check if parent_category exists + if (strcmp(parent_category, "0") && !xbt_dict_get_or_null (created_categories, parent_category)){ + THROW1 (tracing_error, TRACE_ERROR_CATEGORY_NOT_DEFINED, "Category (used as parent) %s is not created", parent_category); + } + //check if category is created + if (xbt_dict_get_or_null (created_categories, category)){ + THROW1 (tracing_error, TRACE_ERROR_CATEGORY_ALREADY_DEFINED, "Category %s is already created", type); + } + + pajeCreateContainer(MSG_get_clock(), category, type, parent_category, category); + + /* for registering application categories on top of platform */ + char state[100]; + snprintf (state, 100, "b%s", category); + if (IS_TRACING_PLATFORM) pajeDefineVariableType (state, "LINK", state); + snprintf (state, 100, "p%s", category); + if (IS_TRACING_PLATFORM) pajeDefineVariableType (state, "HOST", state); + + xbt_dict_set (created_categories, category, xbt_strdup("1"), xbt_free); +} + +void TRACE_set_mask (int mask) +{ + trace_mask = mask; +} + +#endif /* HAVE_TRACING */ diff --git a/src/instr/msg_process_instr.c b/src/instr/msg_process_instr.c new file mode 100644 index 0000000000..e1b71e109d --- /dev/null +++ b/src/instr/msg_process_instr.c @@ -0,0 +1,134 @@ +/* + * msg_process_instr.c + * + * Created on: Feb 24, 2010 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + +#ifdef HAVE_TRACING + +static xbt_dict_t process_containers = NULL; + +void __TRACE_msg_process_init (void) +{ + process_containers = xbt_dict_new(); +} + +void __TRACE_msg_process_location (m_process_t process) +{ + char name[200], alias[200]; + m_host_t host = MSG_process_get_host (process); + TRACE_process_container (process, name, 200); + TRACE_process_alias_container (process, host, alias, 200); + + //check if process_alias container is already created + if (!xbt_dict_get_or_null (process_containers, alias)){ + if (IS_TRACING_PROCESSES) pajeCreateContainer (MSG_get_clock(), alias, "PROCESS", MSG_host_get_name(host), name); + if (IS_TRACING_PROCESSES) pajePushState (MSG_get_clock(), "presence", alias, "1"); + xbt_dict_set (process_containers, xbt_strdup(alias), xbt_strdup("1"), xbt_free); + } +} + +/* + * TRACE_msg_set_process_category: tracing interface function + */ +void TRACE_msg_set_process_category (m_process_t process, const char *category) +{ + if (!IS_TRACING) return; + + //set process category + process->category = xbt_new (char, strlen (category)+1); + strncpy (process->category, category, strlen(category)+1); + + //create container of type "PROCESS" to indicate location + __TRACE_msg_process_location (process); + + //create container of type "process" to indicate behavior + char name[200]; + TRACE_process_container (process, name, 200); + if (IS_TRACING_PROCESSES) pajeCreateContainer (MSG_get_clock(), name, "process", category, name); + if (IS_TRACING_PROCESSES) pajeSetState (MSG_get_clock(), "process-state", name, "executing"); +} + +/* + * Instrumentation functions to trace MSG processes (m_process_t) + */ +void TRACE_msg_process_change_host (m_process_t process, m_host_t old_host, m_host_t new_host) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char alias[200]; + TRACE_process_alias_container (process, old_host, alias, 200); + if (IS_TRACING_PROCESSES) pajePopState (MSG_get_clock(), "presence", alias); + + __TRACE_msg_process_location (process); + TRACE_process_alias_container (process, new_host, alias, 200); + if (IS_TRACING_PROCESSES) pajePushState (MSG_get_clock(), "presence", alias, "1"); +} + +void TRACE_msg_process_kill (m_process_t process) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char name[200]; + TRACE_process_container (process, name, 200); + pajeDestroyContainer (MSG_get_clock(), "process", name); +} + +void TRACE_msg_process_suspend (m_process_t process) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char name[200]; + TRACE_process_container (process, name, 200); + pajeSetState (MSG_get_clock(), "process-state", name, "suspend"); +} + +void TRACE_msg_process_resume (m_process_t process) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char name[200]; + TRACE_process_container (process, name, 200); + pajeSetState (MSG_get_clock(), "process-state", name, "executing"); +} + +void TRACE_msg_process_sleep_in (m_process_t process) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char name[200]; + TRACE_process_container (process, name, 200); + pajeSetState (MSG_get_clock(), "process-state", name, "sleep"); +} + +void TRACE_msg_process_sleep_out (m_process_t process) +{ + if (!IS_TRACING_PROCESSES || !IS_TRACED(process)) return; + + char name[200]; + TRACE_process_container (process, name, 200); + pajeSetState (MSG_get_clock(), "process-state", name, "executing"); +} + +void TRACE_msg_process_end (m_process_t process) +{ + if (!IS_TRACED(process)) return; + + char name[200], alias[200]; + m_host_t host = MSG_process_get_host (process); + TRACE_process_container (process, name, 200); + TRACE_process_alias_container (process, host, alias, 200); + if (IS_TRACING_PROCESSES) pajeDestroyContainer (MSG_get_clock(), "process", name); + if (IS_TRACING_PROCESSES) pajeDestroyContainer (MSG_get_clock(), "PROCESS", alias); +} + +#endif diff --git a/src/instr/msg_task_instr.c b/src/instr/msg_task_instr.c new file mode 100644 index 0000000000..41583bb456 --- /dev/null +++ b/src/instr/msg_task_instr.c @@ -0,0 +1,171 @@ +/* + * msg.c + * + * Created on: Nov 24, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + +#ifdef HAVE_TRACING + +static xbt_dict_t current_task_category = NULL; + +void __TRACE_msg_init (void) +{ + current_task_category = xbt_dict_new(); +} + +void __TRACE_current_category_set (m_task_t task) +{ + char processid[100]; + snprintf (processid, 100, "%p", SIMIX_process_self()); + xbt_dict_set (current_task_category, processid, xbt_strdup (task->category), xbt_free); +} + +void __TRACE_current_category_unset () +{ + char processid[100]; + snprintf (processid, 100, "%p", SIMIX_process_self()); + xbt_dict_remove (current_task_category, processid); +} + +char *__TRACE_current_category_get (smx_process_t proc) +{ + char processid[100]; + snprintf (processid, 100, "%p", proc); + return xbt_dict_get_or_null (current_task_category, processid); +} + +void __TRACE_task_location (m_task_t task) +{ + char container[200]; + m_process_t process = MSG_process_self(); + m_host_t host = MSG_process_get_host (process); + if (IS_TRACING_PROCESSES){ + //container is a process + TRACE_process_alias_container (process, host, container, 200); + __TRACE_msg_process_location (process); + }else{ + //container is a host + TRACE_host_container (host, container, 200); + } + + char name[200], alias[200]; + TRACE_task_container (task, name, 200); + TRACE_task_alias_container (task, process, host, alias, 200); + if (IS_TRACING_TASKS) pajeCreateContainer (MSG_get_clock(), alias, "TASK", container, name); +} + +/* + * TRACE_msg_set_task_category: tracing interface function + */ +void TRACE_msg_set_task_category(m_task_t task, const char *category) +{ + if (!IS_TRACING) return; + + //set task category + task->category = xbt_new (char, strlen (category)+1); + strncpy(task->category, category, strlen(category)+1); + + char name[200];//, alias[200], process_alias[200]; + TRACE_task_container (task, name, 200); + //create container of type "task" to indicate behavior + if (IS_TRACING_TASKS) pajeCreateContainer (MSG_get_clock(), name, "task", category, name); + if (IS_TRACING_TASKS) pajePushState (MSG_get_clock(), "task-state", name, "created"); + + //tracing task location based on process/host + __TRACE_task_location (task); +} + +/* MSG_task_create related function*/ +void TRACE_msg_task_create (m_task_t task) +{ + static long long counter = 0; + task->counter = counter++; + task->category = NULL; +} + +/* MSG_task_execute related functions */ +void TRACE_msg_task_execute_start (m_task_t task) +{ + if (!IS_TRACING || !IS_TRACED(task)) return; + + char name[200]; + TRACE_task_container (task, name, 200); + if (IS_TRACING_TASKS) pajePushState (MSG_get_clock(), "task-state", name, "execute"); + + __TRACE_current_category_set (task); +} + +void TRACE_msg_task_execute_end (m_task_t task) +{ + if (!IS_TRACING || !IS_TRACED(task)) return; + + char name[200]; + TRACE_task_container (task, name, 200); + if (IS_TRACING_TASKS) pajePopState (MSG_get_clock(), "task-state", name); + + __TRACE_current_category_unset(); +} + +/* MSG_task_destroy related functions */ +void TRACE_msg_task_destroy (m_task_t task) +{ + if (!IS_TRACING || !IS_TRACED(task)) return; + + char name[200]; + TRACE_task_container (task, name, 200); + if (IS_TRACING_TASKS) pajeDestroyContainer (MSG_get_clock(), "task", name); + + //free category + xbt_free (task->category); + return; +} + +/* MSG_task_get related functions */ +void TRACE_msg_task_get_start (void) +{ + if (!IS_TRACING) return; +} + +void TRACE_msg_task_get_end (double start_time, m_task_t task) +{ + if (!IS_TRACING || !IS_TRACED(task)) return; + + char name[200]; + TRACE_task_container (task, name, 200); + if (IS_TRACING_TASKS) pajePopState (MSG_get_clock(), "task-state", name); + + //tracing task location based on process/host + __TRACE_task_location (task); +} + +/* MSG_task_put related functions */ +int TRACE_msg_task_put_start (m_task_t task) +{ + if (!IS_TRACING || !IS_TRACED(task)) return 0; + + char name[200]; + TRACE_task_container (task, name, 200); + if (IS_TRACING_TASKS) pajePopState (MSG_get_clock(), "task-state", name); + if (IS_TRACING_TASKS) pajePushState (MSG_get_clock(), "task-state", name, "communicate"); + + __TRACE_current_category_set (task); + return 1; +} + +void TRACE_msg_task_put_end (void) +{ + if (!IS_TRACING) return; + + __TRACE_current_category_unset (); +} + +#endif diff --git a/src/instr/paje.c b/src/instr/paje.c new file mode 100644 index 0000000000..ee2f22cc01 --- /dev/null +++ b/src/instr/paje.c @@ -0,0 +1,448 @@ +/* + * general.c + * + * Created on: Oct 7, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + +#ifdef HAVE_TRACING + +static FILE *tracing_file = NULL; +int tracing_active = 0; + +static int pajeDefineContainerTypeId = 0; +static int pajeDefineStateTypeId = 1; +static int pajeDefineEntityValueId = 2; +static int pajeDefineEventTypeId = 3; +static int pajeDefineLinkTypeId = 4; +static int pajeCreateContainerId = 5; +static int pajeSetStateId = 6; +static int pajePushStateWithHostId = 7; +static int pajePopStateId = 8; +static int pajeDestroyContainerId = 9; +static int pajeSetStateWithHostId = 10; +static int pajeSetStateWithHostCommCompId = 11; +static int pajeStartLinkId = 12; +static int pajeEndLinkId = 13; +static int pajeCreateContainerWithPowerId = 14; +static int pajeStartLinkWithBandwidthLatencyId = 15; +static int pajePushStateWithPowerUsedId = 16; +static int pajePushStateWithBandwidthUsedId = 17; +static int pajeSetStateWithPowerUsedId = 18; +static int pajePushStateId = 19; +static int pajeCreateContainerWithBandwidthLatencyId = 20; +static int pajeCreateContainerWithBandwidthLatencySrcDstId = 21; +static int pajeSetVariableId = 22; +static int pajeAddVariableId = 23; +static int pajeSubVariableId = 24; +static int pajeDefineVariableTypeId = 25; + +#define TRACE_LINE_SIZE 1000 + +void TRACE_paje_start (FILE *file) +{ + tracing_file = file; + tracing_active = 1; +} + +FILE *TRACE_paje_end (void) +{ + tracing_active = 0; + return tracing_file; +} + + +void TRACE_paje_create_header(void) { + if (!tracing_active) + return; + fprintf( + tracing_file, + " \ +%%EventDef PajeDefineContainerType %d \n\ +%% Alias string \n\ +%% ContainerType string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeDefineStateType %d \n\ +%% Alias string \n\ +%% ContainerType string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeDefineEntityValue %d \n\ +%% Alias string \n\ +%% EntityType string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeDefineEventType %d \n\ +%% Alias string \n\ +%% EntityType string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeDefineLinkType %d \n\ +%% Alias string \n\ +%% ContainerType string \n\ +%% SourceContainerType string \n\ +%% DestContainerType string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeCreateContainer %d \n\ +%% Time date \n\ +%% Alias string \n\ +%% Type string \n\ +%% Container string \n\ +%% Name string \n\ +%%EndEventDef \n\ +%%EventDef PajeDestroyContainer %d \n\ +%% Time date \n\ +%% Type string \n\ +%% Container string \n\ +%%EndEventDef \n\ +%%EventDef PajeSetState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%%EndEventDef\n\ +%%EventDef PajeSetState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% Host string\n\ +%%EndEventDef\n\ +%%EventDef PajePushState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% Host string \n\ +%%EndEventDef\n\ +%%EventDef PajePopState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%%EndEventDef\n\ +%%EventDef PajeSetState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% Host string\n\ +%% Comm string\n\ +%% Comp string\n\ +%%EndEventDef\n\ +%%EventDef PajeStartLink %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% SourceContainer string \n\ +%% Key string \n\ +%%EndEventDef\n\ +%%EventDef PajeEndLink %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% DestContainer string \n\ +%% Key string \n\ +%%EndEventDef\n\ +%%EventDef PajeCreateContainer %d \n\ +%% Time date \n\ +%% Alias string \n\ +%% Type string \n\ +%% Container string \n\ +%% Name string \n\ +%% Power string \n\ +%%EndEventDef \n\ +%%EventDef PajeStartLink %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% SourceContainer string \n\ +%% Key string \n\ +%% Bandwidth string \n\ +%% Latency string \n\ +%%EndEventDef\n\ +%%EventDef PajePushState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% PowerUsed string \n\ +%%EndEventDef\n\ +%%EventDef PajePushState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% BandwidthUsed string \n\ +%%EndEventDef\n\ +%%EventDef PajeSetState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%% PowerUsed string \n\ +%%EndEventDef\n\ +%%EventDef PajePushState %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%%EndEventDef\n\ +%%EventDef PajeCreateContainer %d \n\ +%% Time date \n\ +%% Alias string \n\ +%% Type string \n\ +%% Container string \n\ +%% Name string \n\ +%% Bandwidth string \n\ +%% Latency string \n\ +%%EndEventDef \n\ +%%EventDef PajeCreateContainer %d \n\ +%% Time date \n\ +%% Alias string \n\ +%% Type string \n\ +%% Container string \n\ +%% Name string \n\ +%% Bandwidth string \n\ +%% Latency string \n\ +%% SrcHost string \n\ +%% DstHost string \n\ +%%EndEventDef \n\ +%%EventDef PajeSetVariable %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%%EndEventDef\n\ +%%EventDef PajeAddVariable %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%%EndEventDef\n\ +%%EventDef PajeSubVariable %d \n\ +%% Time date \n\ +%% EntityType string \n\ +%% Container string \n\ +%% Value string \n\ +%%EndEventDef\n\ +%%EventDef PajeDefineVariableType %d \n\ +%% Alias string \n\ +%% ContainerType string \n\ +%% Name string \n\ +%%EndEventDef \n", + pajeDefineContainerTypeId, pajeDefineStateTypeId, pajeDefineEntityValueId, + pajeDefineEventTypeId, pajeDefineLinkTypeId, pajeCreateContainerId, + pajeDestroyContainerId, pajeSetStateId, pajeSetStateWithHostId, + pajePushStateWithHostId, pajePopStateId, pajeSetStateWithHostCommCompId, + pajeStartLinkId, pajeEndLinkId, pajeCreateContainerWithPowerId, + pajeStartLinkWithBandwidthLatencyId, pajePushStateWithPowerUsedId, + pajePushStateWithBandwidthUsedId, pajeSetStateWithPowerUsedId, + pajePushStateId, pajeCreateContainerWithBandwidthLatencyId, + pajeCreateContainerWithBandwidthLatencySrcDstId, + pajeSetVariableId, + pajeAddVariableId, + pajeSubVariableId, + pajeDefineVariableTypeId); +} + +/* internal to this file */ +static void __pajeCreateContainer (char *output, int len, int eventid, double time, const char *alias, const char *type, + const char *container, const char *name) +{ + snprintf (output, len, "%d %.15lf %s %s %s %s", eventid, time, + alias, type, container, name); +} + +static void __pajeSetState (char *output, int len, int eventid, double time, const char *entityType, const char *container, const char *value) +{ + snprintf (output, len, "%d %.15lf %s %s %s", eventid, time, entityType, container, value); +} + +static void __pajeSetVariable (char *output, int len, int eventid, double time, const char *entityType, const char *container, const char *value) +{ + snprintf (output, len, "%d %.15lf %s %s %s", eventid, time, entityType, container, value); +} + +static void __pajeStartLink (char *output, int len, int eventid, double time, const char *entityType, const char *container, const char *value, +const char *sourceContainer, const char *key) +{ + snprintf(output, len, "%d %.15lf %s %s %s %s %s", eventid, time, entityType, container, value, sourceContainer, key); +} + + +/* internal do the instrumentation module */ +void pajeDefineContainerType(const char *alias, const char *containerType, + const char *name) { + fprintf(tracing_file, "%d %s %s %s\n", pajeDefineContainerTypeId, alias, + containerType, name); +} + +void pajeDefineStateType(const char *alias, const char *containerType, + const char *name) { + fprintf(tracing_file, "%d %s %s %s\n", pajeDefineStateTypeId, alias, + containerType, name); +} + +void pajeDefineEventType(const char *alias, const char *containerType, + const char *name) { + fprintf(tracing_file, "%d %s %s %s\n", pajeDefineEventTypeId, alias, + containerType, name); +} + +void pajeDefineLinkType(const char *alias, const char *containerType, + const char *sourceContainerType, const char *destContainerType, + const char *name) { + fprintf(tracing_file, "%d %s %s %s %s %s\n", pajeDefineLinkTypeId, alias, + containerType, sourceContainerType, destContainerType, name); +} + +void pajeCreateContainer(double time, const char *alias, const char *type, const char *container, const char *name) { + char line[TRACE_LINE_SIZE]; + __pajeCreateContainer (line, TRACE_LINE_SIZE, pajeCreateContainerId, time, alias, type, container, name); + fprintf (tracing_file, "%s\n", line); +} + +void pajeCreateContainerWithPower (double time, const char *alias, const char *type, const char *container, const char *name, double power) +{ + char line[TRACE_LINE_SIZE]; + __pajeCreateContainer (line, TRACE_LINE_SIZE, pajeCreateContainerWithPowerId, time, alias, type, container, name); + fprintf (tracing_file, "%s %f\n", line, power); +} + +void pajeCreateContainerWithBandwidthLatency (double time, const char *alias, const char *type, const char *container, const char *name, double bw, double lat) +{ + char line[TRACE_LINE_SIZE]; + __pajeCreateContainer (line, TRACE_LINE_SIZE, pajeCreateContainerWithBandwidthLatencyId, time, alias, type, container, name); + fprintf (tracing_file, "%s %f %f\n", line, bw, lat); +} + + +void pajeCreateContainerWithBandwidthLatencySrcDst (double time, const char *alias, const char *type, const char *container, const char *name, double bw, double lat, const char *src, const char *dst) +{ + char line[TRACE_LINE_SIZE]; + __pajeCreateContainer (line, TRACE_LINE_SIZE, pajeCreateContainerWithBandwidthLatencySrcDstId, time, alias, type, container, name); + fprintf (tracing_file, "%s %f %f %s %s\n", line, bw, lat, src, dst); +} + + +void pajeDestroyContainer (double time, const char *type, const char *container) +{ + fprintf(tracing_file, "%d %.15lf %s %s\n", pajeDestroyContainerId, time, type, container); +} + +void pajeSetState (double time, const char *entityType, const char *container, const char *value) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajeSetStateId, time, entityType, container, value); + fprintf(tracing_file, "%s\n", line); +} + +void pajeSetStateWithPowerUsed (double time, const char *entityType, const char *container, const char *value, double powerUsed) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajeSetStateWithPowerUsedId, time, entityType, container, value); + fprintf(tracing_file, "%s %f\n", line, powerUsed); +} + +void pajeSetStateWithHost (double time, const char *entityType, const char *container, const char *value, const char *host) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajeSetStateWithHostId, time, entityType, container, value); + fprintf(tracing_file, "%s %s\n", line, host); +} + +void pajePushState (double time, const char *entityType, const char *container, const char *value) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajePushStateId, time, entityType, container, value); + fprintf(tracing_file, "%s\n", line); +} + +void pajePushStateWithHost (double time, const char *entityType, const char *container, const char *value, const char *host) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajePushStateWithHostId, time, entityType, container, value); + fprintf(tracing_file, "%s %s\n", line, host); +} + +void pajePushStateWithPowerUsed (double time, const char *entityType, const char *container, const char *value, double powerUsed) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajePushStateWithPowerUsedId, time, entityType, container, value); + fprintf(tracing_file, "%s %f\n", line, powerUsed); +} + +void pajePushStateWithBandwidthUsed (double time, const char *entityType, const char *container, const char *value, double bwUsed) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetState (line, TRACE_LINE_SIZE, pajePushStateWithBandwidthUsedId, time, entityType, container, value); + fprintf(tracing_file, "%s %f\n", line, bwUsed); +} + +void pajePopState (double time, const char *entityType, const char *container) +{ + fprintf(tracing_file, "%d %.15lf %s %s\n", pajePopStateId, time, entityType, container); +} + +void pajeStartLink (double time, const char *entityType, const char *container, const char *value, + const char *sourceContainer, const char *key) +{ + char line[TRACE_LINE_SIZE]; + __pajeStartLink (line, TRACE_LINE_SIZE, pajeStartLinkId, time, entityType, container, value, sourceContainer, key); + fprintf (tracing_file, "%s\n", line); +} + +void pajeStartLinkWithBandwidthLatency (double time, const char *entityType, const char *container, const char *value, + const char *sourceContainer, const char *key, double bw, double lat) +{ + char line[TRACE_LINE_SIZE]; + __pajeStartLink (line, TRACE_LINE_SIZE, pajeStartLinkWithBandwidthLatencyId, time, entityType, container, value, sourceContainer, key); + fprintf (tracing_file, "%s %f %f\n", line, bw, lat); +} + +void pajeEndLink (double time, const char *entityType, const char *container, const char *value, + const char *destContainer, const char *key) +{ + fprintf(tracing_file, "%d %.15lf %s %s %s %s %s\n", pajeEndLinkId, time, entityType, container, value, destContainer, key); +} + +void pajeDefineVariableType(const char *alias, const char *containerType, const char *name) { + fprintf(tracing_file, "%d %s %s %s\n", pajeDefineVariableTypeId, alias, containerType, name); +} + + +void pajeSetVariable (double time, const char *entityType, const char *container, const char *value) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetVariable (line, TRACE_LINE_SIZE, pajeSetVariableId, time, entityType, container, value); + fprintf(tracing_file, "%s\n", line); +} + +void pajeAddVariable (double time, const char *entityType, const char *container, const char *value) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetVariable (line, TRACE_LINE_SIZE, pajeAddVariableId, time, entityType, container, value); + fprintf(tracing_file, "%s\n", line); +} + +void pajeSubVariable (double time, const char *entityType, const char *container, const char *value) +{ + char line[TRACE_LINE_SIZE]; + __pajeSetVariable (line, TRACE_LINE_SIZE, pajeSubVariableId, time, entityType, container, value); + fprintf(tracing_file, "%s\n", line); +} + +#endif diff --git a/src/instr/private.h b/src/instr/private.h new file mode 100644 index 0000000000..09bc980ceb --- /dev/null +++ b/src/instr/private.h @@ -0,0 +1,128 @@ +/* + * private.h + * + * Created on: Nov 23, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#ifndef INSTR_PRIVATE_H_ +#define INSTR_PRIVATE_H_ + +#include "instr/config.h" + +#ifdef HAVE_TRACING + +extern int tracing_active; /* declared in paje.c */ +extern int trace_mask; /* declared in interface.c */ + +#define IS_TRACING (tracing_active) +#define IS_TRACED(n) (n->category) +#define IS_TRACING_TASKS ((TRACE_TASK)&trace_mask) +#define IS_TRACING_PLATFORM ((TRACE_PLATFORM)&trace_mask) +#define IS_TRACING_PROCESSES ((TRACE_PROCESS)&trace_mask) + +#include "instr/instr.h" +#include "msg/msg.h" +#include "simix/private.h" + +/* from paje.c */ +void TRACE_paje_create_header(void); +void TRACE_paje_start (FILE *file); +FILE *TRACE_paje_end (void); +void pajeDefineContainerType(const char *alias, const char *containerType, const char *name); +void pajeDefineStateType(const char *alias, const char *containerType, const char *name); +void pajeDefineEventType(const char *alias, const char *containerType, const char *name); +void pajeDefineLinkType(const char *alias, const char *containerType, const char *sourceContainerType, const char *destContainerType, const char *name); +void pajeCreateContainer(double time, const char *alias, const char *type, const char *container, const char *name); +void pajeCreateContainerWithPower (double time, const char *alias, const char *type, const char *container, const char *name, double power); +void pajeCreateContainerWithBandwidthLatency (double time, const char *alias, const char *type, const char *container, const char *name, double bw, double lat); +void pajeCreateContainerWithBandwidthLatencySrcDst (double time, const char *alias, const char *type, const char *container, const char *name, double bw, double lat, const char *src, const char *dst); +void pajeDestroyContainer (double time, const char *type, const char *container); +void pajeSetState (double time, const char *entityType, const char *container, const char *value); +void pajeSetStateWithPowerUsed (double time, const char *entityType, const char *container, const char *value, double powerUsed); +void pajeSetStateWithHost (double time, const char *entityType, const char *container, const char *value, const char *host); +void pajePushState (double time, const char *entityType, const char *container, const char *value); +void pajePushStateWithHost (double time, const char *entityType, const char *container, const char *value, const char *host); +void pajePushStateWithPowerUsed (double time, const char *entityType, const char *container, const char *value, double powerUsed); +void pajePushStateWithBandwidthUsed (double time, const char *entityType, const char *container, const char *value, double bwUsed); +void pajePopState (double time, const char *entityType, const char *container); +void pajeStartLink (double time, const char *entityType, const char *container, const char *value, const char *sourceContainer, const char *key); +void pajeStartLinkWithBandwidthLatency (double time, const char *entityType, const char *container, const char *value, const char *sourceContainer, const char *key, double bw, double lat); +void pajeEndLink (double time, const char *entityType, const char *container, const char *value, const char *destContainer, const char *key); +void pajeDefineVariableType(const char *alias, const char *containerType, const char *name); +void pajeSetVariable (double time, const char *entityType, const char *container, const char *value); +void pajeAddVariable (double time, const char *entityType, const char *container, const char *value); +void pajeSubVariable (double time, const char *entityType, const char *container, const char *value); + +/* from general.c */ +char *TRACE_paje_msg_container (m_task_t task, char *host, char *output, int len); +char *TRACE_paje_smx_container (smx_action_t action, int seqnumber, char *host, char *output, int len); +char *TRACE_paje_surf_container (void *action, int seqnumber, char *output, int len); +char *TRACE_host_container (m_host_t host, char *output, int len); +char *TRACE_task_container (m_task_t task, char *output, int len); +char *TRACE_process_container (m_process_t process, char *output, int len); +char *TRACE_process_alias_container (m_process_t process, m_host_t host, char *output, int len); +char *TRACE_task_alias_container (m_task_t task, m_process_t process, m_host_t host, char *output, int len); + +/* declaration of instrumentation functions from msg_task_instr.c */ +void __TRACE_msg_init (void); +void __TRACE_current_category_set (m_task_t task); +void __TRACE_current_category_unset (void); +char *__TRACE_current_category_get (smx_process_t proc); +void __TRACE_task_location (m_task_t task); +void TRACE_msg_task_create (m_task_t task); +void TRACE_msg_task_execute_start (m_task_t task); +void TRACE_msg_task_execute_end (m_task_t task); +void TRACE_msg_task_destroy (m_task_t task); +void TRACE_msg_task_get_start(void); +void TRACE_msg_task_get_end (double start_time, m_task_t task); +int TRACE_msg_task_put_start (m_task_t task); //returns TRUE if the task_put_end must be called +void TRACE_msg_task_put_end (void); + +/* declaration of instrumentation functions from msg_process_instr.c */ +void __TRACE_msg_process_init (void); +void __TRACE_msg_process_location (m_process_t process); +void TRACE_msg_process_change_host (m_process_t process, m_host_t old_host, m_host_t new_host); +void TRACE_msg_process_kill (m_process_t process); +void TRACE_msg_process_suspend (m_process_t process); +void TRACE_msg_process_resume (m_process_t process); +void TRACE_msg_process_sleep_in (m_process_t process); //called from msg/gos.c +void TRACE_msg_process_sleep_out (m_process_t process); +void TRACE_msg_process_end (m_process_t process); + +/* from smx.c */ +void TRACE_smx_action_execute (smx_action_t act); +void TRACE_smx_action_communicate (smx_action_t act, smx_process_t proc); +void TRACE_smx_action_destroy (smx_action_t act); + +/* from surf.c */ +void __TRACE_surf_init (void); +void __TRACE_surf_finalize (void); +void __TRACE_surf_check_variable_set_to_zero (double now, const char *variable, const char *resource); +void __TRACE_surf_update_action_state_resource (double now, double delta, const char *type, const char *name, double value); +void __TRACE_surf_set_resource_variable (double date, const char *variable, const char *resource, double value); +void TRACE_surf_update_action_state (void *surf_action, smx_action_t smx_action, double value, const char *stateValue, double now, double delta); +void TRACE_surf_update_action_state_net_resource (const char *name, smx_action_t smx_action, double value, double now, double delta); +void TRACE_surf_update_action_state_cpu_resource (const char *name, smx_action_t smx_action, double value, double now, double delta); +void TRACE_surf_net_link_new (char *name, double bw, double lat); +void TRACE_surf_cpu_new (char *name, double power); +void TRACE_surf_cpu_set_power (double date, char *resource, double power); +void TRACE_surf_link_set_bandwidth (double date, char *resource, double bandwidth); +void TRACE_surf_link_set_latency (double date, char *resource, double latency); +void TRACE_surf_routing_full_parse_end (char *link_name, int src, int dst); +void TRACE_surf_missing_link (void); +void TRACE_surf_define_host_id (const char *name, int host_id); +//for tracing gtnets +void TRACE_surf_gtnets_communicate (void *action, int src, int dst); +int TRACE_surf_gtnets_get_src (void *action); +int TRACE_surf_gtnets_get_dst (void *action); +void TRACE_surf_gtnets_destroy (void *action); + +#endif + +#endif /* PRIVATE_H_ */ diff --git a/src/instr/smx_instr.c b/src/instr/smx_instr.c new file mode 100644 index 0000000000..675ec54c18 --- /dev/null +++ b/src/instr/smx_instr.c @@ -0,0 +1,53 @@ +/* + * smx.c + * + * Created on: Nov 24, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + +#ifdef HAVE_TRACING + +static long long int counter = 0; /* to uniquely identify simix actions */ + +void TRACE_smx_action_execute (smx_action_t act) +{ + if (!IS_TRACING) return; + + act->counter = counter++; + char *category = __TRACE_current_category_get (SIMIX_process_self()); + if (category){ + act->category = xbt_new (char, strlen (category)+1); + strncpy (act->category, category, strlen(category)+1); + } +} + +void TRACE_smx_action_communicate (smx_action_t act, smx_process_t proc) +{ + if (!IS_TRACING) return; + + act->counter = counter++; + char *category = __TRACE_current_category_get (proc); + if (category){ + act->category = xbt_new (char, strlen (category)+1); + strncpy (act->category, category, strlen(category)+1); + } +} + +void TRACE_smx_action_destroy (smx_action_t act) +{ + if (!IS_TRACING || !IS_TRACED(act)) return; + + if (act->category){ + xbt_free (act->category); + } +} + +#endif diff --git a/src/instr/surf_instr.c b/src/instr/surf_instr.c new file mode 100644 index 0000000000..81a2be7c3c --- /dev/null +++ b/src/instr/surf_instr.c @@ -0,0 +1,418 @@ +/* + * surf.c + * + * Created on: Nov 27, 2009 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" + +#ifdef HAVE_TRACING + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(tracing_surf,tracing,"Tracing Surf"); + +#define VARIABLE_SEPARATOR '#' + +static xbt_dict_t hosts_id; +static xbt_dict_t created_links; +static xbt_dict_t link_bandwidth; +static xbt_dict_t link_latency; +//static xbt_dict_t platform_variable_last_value; /* to control the amount of add/sub variables events*/ +//static xbt_dict_t platform_variable_last_time; /* to control the amount of add/sub variables events*/ + +static xbt_dict_t last_platform_variables; /* to control the amount of add/sub variables events: + dict with key {RESOURCE_NAME}#Time or {RESOURCE_NAME}#Value of dict with variables types == string */ + +static xbt_dict_t platform_variables; /* host or link name -> array of categories */ + +static xbt_dict_t resource_variables; /* (host|link)#variable -> value */ + +/* to trace gtnets */ +static xbt_dict_t gtnets_src; /* %p (action) -> %s */ +static xbt_dict_t gtnets_dst; /* %p (action) -> %s */ + +void __TRACE_surf_init (void) +{ + hosts_id = xbt_dict_new(); + created_links = xbt_dict_new(); + link_bandwidth = xbt_dict_new(); + link_latency = xbt_dict_new(); + platform_variables = xbt_dict_new(); + + //platform_variable_last_value = xbt_dict_new(); + //platform_variable_last_time = xbt_dict_new(); + + last_platform_variables = xbt_dict_new(); + + resource_variables = xbt_dict_new (); + + gtnets_src = xbt_dict_new (); + gtnets_dst = xbt_dict_new (); +} + +static char *strsplit (char *input, int field, char del) //caller should free the returned string +{ + int length = strlen(input), i; + int s = 0, e = length+1; + int current_field = 0; + for (i = 0; i < length; i++){ + if (input[i] == del){ + if (current_field == field){ + e = i-1; + break; + }else{ + s = i+1; + current_field++; + } + } + } + //copy string from s to e (with length equal to e-s) and return + char *ret = malloc ((e-s+2)*sizeof(char)); + strncpy (ret, input+s, e-s+1); + ret[e-s+1] = '\0'; + return ret; +} + +void __TRACE_surf_finalize (void) +{ + if (!IS_TRACING_PLATFORM) return; + if (!xbt_dict_length(last_platform_variables)){ + return; + }else{ + xbt_dict_cursor_t cursor = NULL; + unsigned int cursor_ar = 0; + char *key, *value, *res; + char resource[200]; + + /* get all resources from last_platform_variables */ + xbt_dynar_t resources = xbt_dynar_new(sizeof(char)*200, xbt_free); + xbt_dict_foreach(last_platform_variables, cursor, key, value) { + res = strsplit (key, 0, VARIABLE_SEPARATOR); + char *aux = strsplit (key, 1, VARIABLE_SEPARATOR); + if (strcmp (aux, "Time") == 0){ //only need to add one of three + xbt_dynar_push (resources, xbt_strdup(res)); + } + free (aux); + free (res); + } + + /* iterate through resources array */ + xbt_dynar_foreach (resources, cursor_ar, resource) { + char timekey[100], valuekey[100], variablekey[100]; + snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR); + snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR); + snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR); + + char *time = xbt_dict_get_or_null (last_platform_variables, timekey); + if (!time) continue; + char *value = xbt_dict_get (last_platform_variables, valuekey); + char *variable = xbt_dict_get (last_platform_variables, variablekey); + pajeSubVariable (atof(time), variable, resource, value); + + //TODO: should remove, but it is causing sigabort + //xbt_dict_remove (last_platform_variables, timekey); + //xbt_dict_remove (last_platform_variables, valuekey); + //xbt_dict_remove (last_platform_variables, variablekey); + } + } +} + +void __TRACE_surf_check_variable_set_to_zero (double now, const char *variable, const char *resource) +{ + /* check if we have to set it to 0 */ + if (!xbt_dict_get_or_null (platform_variables, resource)){ + xbt_dynar_t array = xbt_dynar_new(100*sizeof(char), xbt_free); + xbt_dynar_push (array, xbt_strdup(variable)); + if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0"); + xbt_dict_set (platform_variables, resource, array, xbt_dynar_free_voidp); + }else{ + xbt_dynar_t array = xbt_dict_get (platform_variables, resource); + unsigned int i; + char cat[100]; + int flag = 0; + xbt_dynar_foreach (array, i, cat) { + if (strcmp(variable, cat)==0){ + flag = 1; + } + } + if (flag==0){ + xbt_dynar_push (array, strdup(variable)); + if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0"); + } + } + /* end of check */ +} + +void __TRACE_surf_update_action_state_resource (double now, double delta, const char *variable, const char *resource, double value) +{ + if (!IS_TRACING_PLATFORM) return; + + char valuestr[100]; + snprintf (valuestr, 100, "%f", value); + + /* + //fprintf (stderr, "resource = %s variable = %s (%f -> %f) value = %s\n", resource, variable, now, now+delta, valuestr); + if (1){ + __TRACE_surf_check_variable_set_to_zero (now, variable, resource); + if (IS_TRACING_PLATFORM) pajeAddVariable (now, variable, resource, valuestr); + if (IS_TRACING_PLATFORM) pajeSubVariable (now+delta, variable, resource, valuestr); + return; + } + */ + + /* + * The following code replaces the code above with the objective + * to decrease the size of file because of unnecessary add/sub on + * variables. It should be re-checked before put in production. + */ + + char nowstr[100], nowdeltastr[100]; + snprintf (nowstr, 100, "%.15f", now); + snprintf (nowdeltastr, 100, "%.15f", now+delta); + + char timekey[100], valuekey[100], variablekey[100]; + snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR); + snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR); + snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR); + + char *lastvariable = xbt_dict_get_or_null (last_platform_variables, variablekey); + if (lastvariable == NULL){ + __TRACE_surf_check_variable_set_to_zero (now, variable, resource); + pajeAddVariable (now, variable, resource, valuestr); + xbt_dict_set (last_platform_variables, xbt_strdup (timekey), xbt_strdup (nowdeltastr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup (valuekey), xbt_strdup (valuestr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup (variablekey), xbt_strdup (variable), xbt_free); + }else{ + char *lasttime = xbt_dict_get_or_null (last_platform_variables, timekey); + char *lastvalue = xbt_dict_get_or_null (last_platform_variables, valuekey); + + /* check if it is the same variable */ + if (strcmp(lastvariable, variable) == 0){ /* same variable */ + /* check if lasttime equals now */ + if (atof(lasttime) == now){ /* lastime == now */ + /* check if lastvalue equals valuestr */ + if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */ + xbt_dict_set (last_platform_variables, xbt_strdup(timekey), xbt_strdup(nowdeltastr), xbt_free); + }else{ /* value has changed */ + /* value has changed, subtract previous value, add new one */ + pajeSubVariable (atof(lasttime), variable, resource, lastvalue); + pajeAddVariable (atof(nowstr), variable, resource, valuestr); + xbt_dict_set (last_platform_variables, xbt_strdup(timekey), xbt_strdup(nowdeltastr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup(valuekey), xbt_strdup(valuestr), xbt_free); + } + }else{ /* lasttime != now */ + /* the last time is different from new starting time, subtract to lasttime and add from nowstr */ + pajeSubVariable (atof(lasttime), variable, resource, lastvalue); + pajeAddVariable (atof(nowstr), variable, resource, valuestr); + xbt_dict_set (last_platform_variables, xbt_strdup(timekey), xbt_strdup(nowdeltastr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup(valuekey), xbt_strdup(valuestr), xbt_free); + } + }else{ /* variable has changed */ + pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue); + __TRACE_surf_check_variable_set_to_zero (now, variable, resource); + pajeAddVariable (now, variable, resource, valuestr); + xbt_dict_set (last_platform_variables, xbt_strdup (timekey), xbt_strdup (nowdeltastr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup (valuekey), xbt_strdup (valuestr), xbt_free); + xbt_dict_set (last_platform_variables, xbt_strdup (variablekey), xbt_strdup (variable), xbt_free); + } + } + return; +} + +void __TRACE_surf_set_resource_variable (double date, const char *variable, const char *resource, double value) +{ + if (!IS_TRACING) return; + char aux[100], key[100]; + snprintf (aux, 100, "%f", value); + snprintf (key, 100, "%s%c%s", resource, VARIABLE_SEPARATOR, variable); + + char *last_value = xbt_dict_get_or_null(resource_variables, key); + if (last_value){ + if (atof(last_value) == value){ + return; + } + } + if (IS_TRACING_PLATFORM) pajeSetVariable (date, variable, resource, aux); + xbt_dict_set (resource_variables, xbt_strdup(key), xbt_strdup(aux), xbt_free); +} + +void TRACE_surf_update_action_state (void *surf_action, smx_action_t smx_action, + double value, const char *stateValue, double now, double delta) +{ +} + +void TRACE_surf_update_action_state_net_resource (const char *name, smx_action_t smx_action, double value, double now, double delta) +{ + if (!IS_TRACING || !IS_TRACED(smx_action)) return; + + if (strcmp (name, "__loopback__")==0 || + strcmp (name, "loopback")==0){ //ignore loopback updates + return; + } + + if (value == 0) return; + + if (!xbt_dict_get_or_null (created_links, name)){ + TRACE_surf_missing_link (); + return; + } + + char type[100]; + snprintf (type, 100, "b%s", smx_action->category); + __TRACE_surf_update_action_state_resource (now, delta, type, name, value); + return; +} + +void TRACE_surf_update_action_state_cpu_resource (const char *name, smx_action_t smx_action, double value, double now, double delta) +{ + if (!IS_TRACING || !IS_TRACED(smx_action)) return; + + if (value==0){ + return; + } + + char type[100]; + snprintf (type, 100, "p%s", smx_action->category); + __TRACE_surf_update_action_state_resource (now, delta, type, name, value); + return; +} + +void TRACE_surf_net_link_new (char *name, double bw, double lat) +{ + if (!IS_TRACING) return; + //if (IS_TRACING_PLATFORM) pajeCreateContainerWithBandwidthLatency (SIMIX_get_clock(), name, "LINK", "platform", name, bw, lat); + //save bw and lat information for this link + double *bw_ptr, *lat_ptr; + bw_ptr = xbt_new (double, 1); + lat_ptr = xbt_new (double, 1); + *bw_ptr = bw; + *lat_ptr = lat; + xbt_dict_set (link_bandwidth, xbt_strdup(name), bw_ptr, xbt_free); + xbt_dict_set (link_latency, xbt_strdup(name), lat_ptr, xbt_free); +} + +void TRACE_surf_cpu_new (char *name, double power) +{ + if (!IS_TRACING) return; + if (IS_TRACING_PLATFORM) pajeCreateContainer (SIMIX_get_clock(), name, "HOST", "platform", name); + __TRACE_surf_set_resource_variable (SIMIX_get_clock(), "power", name, power); +} + +void TRACE_surf_routing_full_parse_end (char *link_name, int src, int dst) +{ + if (!IS_TRACING) return; + char srcidstr[100], dstidstr[100]; + snprintf (srcidstr, 100, "%d", src); + snprintf (dstidstr, 100, "%d", dst); + char *srcname = xbt_dict_get (hosts_id, srcidstr); + char *dstname = xbt_dict_get (hosts_id, dstidstr); + + char key[100]; + snprintf (key, 100, "l%d-%d", src, dst); + + if (strcmp (link_name, "__loopback__")==0 || + strcmp (link_name, "loopback")==0){ //ignore loopback updates + return; + } + + if (!xbt_dict_get_or_null (created_links, link_name)){ + //if (IS_TRACING_PLATFORM) pajeStartLink (SIMIX_get_clock(), "edge", "platform", "route", srcname, key); + //if (IS_TRACING_PLATFORM) pajeEndLink (SIMIX_get_clock()+0.1, "edge", "platform", "route", dstname, key); + double *bw = xbt_dict_get (link_bandwidth, link_name); + double *lat = xbt_dict_get (link_latency, link_name); + if (IS_TRACING_PLATFORM) pajeCreateContainerWithBandwidthLatencySrcDst (SIMIX_get_clock(), link_name, "LINK", "platform", link_name, *bw, *lat, srcname, dstname); + __TRACE_surf_set_resource_variable (SIMIX_get_clock(), "bandwidth", link_name, *bw); + __TRACE_surf_set_resource_variable (SIMIX_get_clock(), "latency", link_name, *lat); + xbt_dict_set (created_links, xbt_strdup(link_name), xbt_strdup ("1"), xbt_free); + } +} + +void TRACE_surf_cpu_set_power (double date, char *resource, double power) +{ + __TRACE_surf_set_resource_variable (date, "power", resource, power); +} + +void TRACE_surf_link_set_bandwidth (double date, char *resource, double bandwidth) +{ + __TRACE_surf_set_resource_variable (date, "bandwidth", resource, bandwidth); +} + +void TRACE_surf_link_set_latency (double date, char *resource, double latency) +{ + __TRACE_surf_set_resource_variable (date, "latency", resource, latency); +} + +void TRACE_surf_define_host_id (const char *name, int host_id) +{ + if (!IS_TRACING) return; + char strid[100]; + snprintf (strid, 100, "%d", host_id); + xbt_dict_set (hosts_id, strdup(name), strdup(strid), free); + xbt_dict_set (hosts_id, strdup(strid), strdup(name), free); +} + +/* to trace gtnets */ +void TRACE_surf_gtnets_communicate (void *action, int src, int dst) +{ + if (!IS_TRACING) return; + char key[100], aux[100]; + snprintf (key, 100, "%p", action); + + snprintf (aux, 100, "%d", src); + xbt_dict_set (gtnets_src, xbt_strdup(key), xbt_strdup(aux), xbt_free); + snprintf (aux, 100, "%d", dst); + xbt_dict_set (gtnets_dst, xbt_strdup(key), xbt_strdup(aux), xbt_free); +} + +int TRACE_surf_gtnets_get_src (void *action) +{ + if (!IS_TRACING) return -1; + char key[100]; + snprintf (key, 100, "%p", action); + + char *aux = xbt_dict_get_or_null (gtnets_src, key); + if (aux){ + return atoi(aux); + }else{ + return -1; + } +} + +int TRACE_surf_gtnets_get_dst (void *action) +{ + if (!IS_TRACING) return -1; + char key[100]; + snprintf (key, 100, "%p", action); + + char *aux = xbt_dict_get_or_null (gtnets_dst, key); + if (aux){ + return atoi(aux); + }else{ + return -1; + } +} + +void TRACE_surf_gtnets_destroy (void *action) +{ + if (!IS_TRACING) return; + char key[100]; + snprintf (key, 100, "%p", action); + xbt_dict_remove (gtnets_src, key); + xbt_dict_remove (gtnets_dst, key); +} + +void TRACE_surf_missing_link (void) +{ + CRITICAL0("The trace cannot be done because " + "the platform you are using contains " + "routes with more than one link."); + THROW0(tracing_error, TRACE_ERROR_COMPLEX_ROUTES, "Tracing failed"); +} + +#endif diff --git a/src/instr/variables_instr.c b/src/instr/variables_instr.c new file mode 100644 index 0000000000..bd1c38adc9 --- /dev/null +++ b/src/instr/variables_instr.c @@ -0,0 +1,75 @@ +/* + * variables_instr.c + * + * Created on: Feb 23, 2010 + * Author: Lucas Schnorr + * License: 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. + * + * Copyright (c) 2009 The SimGrid team. + */ + +#include "instr/private.h" +#include "instr/config.h" +#include "surf/surf_private.h" +#include "surf/network_private.h" + +#ifdef HAVE_TRACING + +extern routing_t used_routing; + +void __TRACE_link_variable (double time, const char *src, const char *dst, const char *variable, double value, const char *what) +{ + if (!IS_TRACING || !IS_TRACING_PLATFORM) return; + + char valuestr[100]; + snprintf (valuestr, 100, "%g", value); + + if (strcmp (what, "declare") == 0){ + pajeDefineVariableType (variable, "LINK", variable); + return; + } + + if (!used_routing) return; + + int src_id, dst_id; + src_id = *(int*)xbt_dict_get(used_routing->host_id,src); + dst_id = *(int*)xbt_dict_get(used_routing->host_id,dst); + xbt_dynar_t route = used_routing->get_route(src_id, dst_id); + + unsigned int i; + void *link_ptr; + xbt_dynar_foreach(route, i, link_ptr) { + char *link = (*(link_CM02_t)link_ptr).lmm_resource.generic_resource.name; + + if (strcmp (what, "set") == 0){ + pajeSetVariable (time, variable, link, valuestr); + }else if (strcmp (what, "add") == 0){ + pajeAddVariable (time, variable, link, valuestr); + }else if (strcmp (what, "sub") == 0){ + pajeSubVariable (time, variable, link, valuestr); + } + } +} + +void __TRACE_host_variable (double time, const char *variable, double value, const char *what) +{ + if (!IS_TRACING || !IS_TRACING_PLATFORM) return; + + char valuestr[100]; + snprintf (valuestr, 100, "%g", value); + + if (strcmp (what, "declare") == 0){ + pajeDefineVariableType (variable, "HOST", variable); + }else if (strcmp (what, "set") == 0){ + pajeSetVariable (time, variable, MSG_host_self()->name, valuestr); + }else if (strcmp (what, "add") == 0){ + pajeAddVariable (time, variable, MSG_host_self()->name, valuestr); + }else if (strcmp (what, "sub") == 0){ + pajeSubVariable (time, variable, MSG_host_self()->name, valuestr); + } +} + + +#endif /* HAVE_TRACING */ diff --git a/src/msg/gos.c b/src/msg/gos.c index 7c8bbf5cc1..f656ec4e79 100644 --- a/src/msg/gos.c +++ b/src/msg/gos.c @@ -42,6 +42,9 @@ MSG_error_t MSG_task_execute(m_task_t task) m_process_t self = MSG_process_self(); e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM; CHECK_HOST(); +#ifdef HAVE_TRACING + TRACE_msg_task_execute_start (task); +#endif simdata = task->simdata; @@ -76,18 +79,27 @@ MSG_error_t MSG_task_execute(m_task_t task) simdata->computation_amount = 0.0; simdata->comm = NULL; simdata->compute = NULL; +#ifdef HAVE_TRACING + TRACE_msg_task_execute_end (task); +#endif MSG_RETURN(MSG_OK); } else if (SIMIX_host_get_state(SIMIX_host_self()) == 0) { /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ SIMIX_action_destroy(task->simdata->compute); simdata->comm = NULL; simdata->compute = NULL; +#ifdef HAVE_TRACING + TRACE_msg_task_execute_end (task); +#endif MSG_RETURN(MSG_HOST_FAILURE); } else { /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ SIMIX_action_destroy(task->simdata->compute); simdata->comm = NULL; simdata->compute = NULL; +#ifdef HAVE_TRACING + TRACE_msg_task_execute_end (task); +#endif MSG_RETURN(MSG_TASK_CANCELLED); } } @@ -228,6 +240,10 @@ MSG_error_t MSG_process_sleep(double nb_sec) smx_mutex_t mutex; smx_cond_t cond; +#ifdef HAVE_TRACING + TRACE_msg_process_sleep_in (MSG_process_self()); +#endif + /* create action to sleep */ act_sleep = SIMIX_action_sleep(SIMIX_process_get_host(proc->simdata->s_process), @@ -256,14 +272,23 @@ MSG_error_t MSG_process_sleep(double nb_sec) if (SIMIX_action_get_state(act_sleep) == SURF_ACTION_DONE) { if (SIMIX_host_get_state(SIMIX_host_self()) == SURF_RESOURCE_OFF) { SIMIX_action_destroy(act_sleep); +#ifdef HAVE_TRACING + TRACE_msg_process_sleep_out (MSG_process_self()); +#endif MSG_RETURN(MSG_HOST_FAILURE); } } else { SIMIX_action_destroy(act_sleep); +#ifdef HAVE_TRACING + TRACE_msg_process_sleep_out (MSG_process_self()); +#endif MSG_RETURN(MSG_HOST_FAILURE); } SIMIX_action_destroy(act_sleep); +#ifdef HAVE_TRACING + TRACE_msg_process_sleep_out (MSG_process_self()); +#endif MSG_RETURN(MSG_OK); } diff --git a/src/msg/m_process.c b/src/msg/m_process.c index 2af1ec4173..c0f57c517d 100644 --- a/src/msg/m_process.c +++ b/src/msg/m_process.c @@ -34,6 +34,9 @@ void __MSG_process_cleanup(void *arg) { /* arg is a pointer to a simix process, we can get the msg process with the field data */ m_process_t proc = ((smx_process_t) arg)->data; +#ifdef HAVE_TRACING + TRACE_msg_process_end (proc); +#endif xbt_fifo_remove(msg_global->process_list, proc); SIMIX_process_cleanup(arg); if (proc->name) { @@ -185,6 +188,9 @@ m_process_t MSG_process_create_with_environment(const char *name, void _MSG_process_kill_from_SIMIX(void *p) { +#ifdef HAVE_TRACING + TRACE_msg_process_kill ((m_process_t) p); +#endif MSG_process_kill((m_process_t) p); } @@ -197,6 +203,10 @@ void MSG_process_kill(m_process_t process) { simdata_process_t p_simdata = process->simdata; +#ifdef HAVE_TRACING + TRACE_msg_process_kill (process); +#endif + DEBUG3("Killing %s(%d) on %s", process->name, p_simdata->PID, p_simdata->m_host->name); @@ -227,6 +237,9 @@ MSG_error_t MSG_process_change_host(m_host_t host) m_process_t process = MSG_process_self(); m_host_t now = process->simdata->m_host; process->simdata->m_host = host; +#ifdef HAVE_TRACING + TRACE_msg_process_change_host (process, now, host); +#endif SIMIX_process_change_host(process->simdata->s_process, now->name, host->name); return MSG_OK; @@ -417,6 +430,10 @@ MSG_error_t MSG_process_suspend(m_process_t process) && (process->simdata)), "Invalid parameters"); CHECK_HOST(); +#ifdef HAVE_TRACING + TRACE_msg_process_suspend (process); +#endif + SIMIX_process_suspend(process->simdata->s_process); MSG_RETURN(MSG_OK); } @@ -434,6 +451,10 @@ MSG_error_t MSG_process_resume(m_process_t process) && (process->simdata)), "Invalid parameters"); CHECK_HOST(); +#ifdef HAVE_TRACING + TRACE_msg_process_resume (process); +#endif + SIMIX_process_resume(process->simdata->s_process); MSG_RETURN(MSG_OK); } diff --git a/src/msg/msg_mailbox.c b/src/msg/msg_mailbox.c index 633a9de8af..b8c72c7f94 100644 --- a/src/msg/msg_mailbox.c +++ b/src/msg/msg_mailbox.c @@ -116,6 +116,10 @@ MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, m_task_t *task, m_host_t host, if (host) THROW_UNIMPLEMENTED; CHECK_HOST(); +#ifdef HAVE_TRACING + TRACE_msg_task_get_start (); + double start_time = MSG_get_clock(); +#endif memset(&comm,0,sizeof(comm)); @@ -152,7 +156,14 @@ MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, m_task_t *task, m_host_t host, } xbt_ex_free(e); } - + + if (ret != MSG_HOST_FAILURE && + ret != MSG_TRANSFER_FAILURE && + ret != MSG_TIMEOUT){ +#ifdef HAVE_TRACING + TRACE_msg_task_get_end (start_time, *task); +#endif + } MSG_RETURN(ret); } @@ -167,6 +178,11 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task, CHECK_HOST(); +#ifdef HAVE_TRACING + int call_end = TRACE_msg_task_put_start (task); //must be after CHECK_HOST() +#endif + + /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; @@ -211,6 +227,8 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, m_task_t task, } process->simdata->waiting_task = NULL; - +#ifdef HAVE_TRACING + if (call_end) TRACE_msg_task_put_end (); +#endif MSG_RETURN(ret); } diff --git a/src/msg/private.h b/src/msg/private.h index 2ac72296c4..dde9f85872 100644 --- a/src/msg/private.h +++ b/src/msg/private.h @@ -18,6 +18,7 @@ #include "xbt/swag.h" #include "xbt/dict.h" #include "xbt/config.h" +#include "instr/private.h" SG_BEGIN_DECL() diff --git a/src/msg/task.c b/src/msg/task.c index acdfacaaef..05a1a3e907 100644 --- a/src/msg/task.c +++ b/src/msg/task.c @@ -72,6 +72,9 @@ m_task_t MSG_task_create(const char *name, double compute_duration, simdata->host_list = NULL; simdata->comp_amount = NULL; simdata->comm_amount = NULL; +#ifdef HAVE_TRACING + TRACE_msg_task_create (task); +#endif return task; } @@ -156,6 +159,9 @@ MSG_error_t MSG_task_destroy(m_task_t task) task->simdata->refcount--; if (task->simdata->refcount > 0) return MSG_OK; +#ifdef HAVE_TRACING + TRACE_msg_task_destroy (task); +#endif if (task->name) free(task->name); diff --git a/src/simix/private.h b/src/simix/private.h index 65e93e92c2..4568983ed6 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -17,6 +17,8 @@ #include "xbt/config.h" #include "xbt/function_types.h" #include "xbt/ex_interface.h" +#include "instr/private.h" +#include "instr/config.h" /******************************** Datatypes ***********************************/ @@ -183,6 +185,10 @@ typedef struct s_smx_action { int refcount; /**< @brief reference counter */ surf_action_t surf_action; /* SURF modeling of computation */ smx_host_t source; +#ifdef HAVE_TRACING + long long int counter; /* simix action unique identifier for instrumentation */ + char *category; /* simix action category for instrumentation */ +#endif } s_smx_action_t; /************************** Configuration support *****************************/ diff --git a/src/simix/smx_action.c b/src/simix/smx_action.c index ab885c7f47..adeea21d09 100644 --- a/src/simix/smx_action.c +++ b/src/simix/smx_action.c @@ -50,7 +50,7 @@ smx_action_t SIMIX_action_communicate(smx_host_t sender, /* initialize them */ act->name = xbt_strdup(name); act->source = sender; - + act->category = NULL; act->surf_action = surf_workstation_model->extension.workstation.communicate(sender->host, @@ -90,6 +90,7 @@ smx_action_t SIMIX_action_execute(smx_host_t host, const char *name, /* initialize them */ act->source = host; act->name = xbt_strdup(name); + act->category = NULL; /* set communication */ act->surf_action = @@ -98,6 +99,9 @@ smx_action_t SIMIX_action_execute(smx_host_t host, const char *name, surf_workstation_model->action_data_set(act->surf_action, act); DEBUG1("Create execute action %p", act); +#ifdef HAVE_TRACING + TRACE_smx_action_execute (act); +#endif return act; } @@ -131,6 +135,7 @@ smx_action_t SIMIX_action_sleep(smx_host_t host, double duration) /* initialize them */ act->source = host; act->name = xbt_strdup(name); + act->category = NULL; act->surf_action = surf_workstation_model->extension.workstation.sleep(host->host, duration); @@ -205,7 +210,9 @@ int SIMIX_action_destroy(smx_action_t action) if (action->surf_action) action->surf_action->model_type->action_unref(action->surf_action); - +#ifdef HAVE_TRACING + TRACE_smx_action_destroy (action); +#endif xbt_free(action); return 1; } @@ -350,6 +357,7 @@ smx_action_t SIMIX_action_parallel_execute(char *name, int host_nb, /* initialize them */ act->name = xbt_strdup(name); + act->category = NULL; /* set action */ diff --git a/src/simix/smx_network.c b/src/simix/smx_network.c index 36ec03c000..9c17f8b87c 100644 --- a/src/simix/smx_network.c +++ b/src/simix/smx_network.c @@ -208,6 +208,9 @@ static inline void SIMIX_communication_start(smx_comm_t comm) comm->act = SIMIX_action_communicate(comm->src_proc->smx_host, comm->dst_proc->smx_host, NULL, comm->task_size, comm->rate); +#ifdef HAVE_TRACING + TRACE_smx_action_communicate (comm->act, comm->src_proc); +#endif /* If any of the process is suspend, create the action but stop its execution, it will be restarted when the sender process resume */ diff --git a/src/surf/cpu.c b/src/surf/cpu.c index d37afd514c..ce88542bf6 100644 --- a/src/surf/cpu.c +++ b/src/surf/cpu.c @@ -62,6 +62,9 @@ static cpu_Cas01_t cpu_new(char *name, double power_peak, xbt_dict_set(surf_model_resource_set(surf_cpu_model), name, cpu, surf_resource_free); +#ifdef HAVE_TRACING + TRACE_surf_cpu_new (name, cpu->power_scale * cpu->power_peak); +#endif return cpu; } @@ -190,6 +193,14 @@ static void cpu_update_actions_state(double now, double delta) xbt_swag_t running_actions = surf_cpu_model->states.running_action_set; xbt_swag_foreach_safe(action, next_action, running_actions) { +#ifdef HAVE_TRACING + TRACE_surf_update_action_state (action, action->generic_action.data, + lmm_variable_getvalue(action->variable), "PowerUsed", now-delta, delta); + cpu_Cas01_t x = lmm_constraint_id(lmm_get_cnst_from_var (cpu_maxmin_system, action->variable, 0)); + + TRACE_surf_update_action_state_cpu_resource (x->generic_resource.name, + action->generic_action.data, lmm_variable_getvalue(action->variable), now-delta, delta); +#endif double_update(&(action->generic_action.remains), lmm_variable_getvalue(action->variable) * delta); if (action->generic_action.max_duration != NO_MAX_DURATION) @@ -218,6 +229,9 @@ static void cpu_update_resource_state(void *id, cpu->power_scale = value; lmm_update_constraint_bound(cpu_maxmin_system, cpu->constraint, cpu->power_scale * cpu->power_peak); +#ifdef HAVE_TRACING + TRACE_surf_cpu_set_power (date, cpu->generic_resource.name, cpu->power_scale * cpu->power_peak); +#endif if (tmgr_trace_event_free(event_type)) cpu->power_event = NULL; } else if (event_type == cpu->state_event) { diff --git a/src/surf/cpu_im.c b/src/surf/cpu_im.c index ca0a98b56a..92e8742706 100644 --- a/src/surf/cpu_im.c +++ b/src/surf/cpu_im.c @@ -53,6 +53,10 @@ static cpu_Cas01_im_t cpu_im_new(char *name, double power_peak, tmgr_trace_t state_trace, xbt_dict_t cpu_properties) { +#ifdef HAVE_TRACING + TRACE_surf_cpu_new (name, power_scale * power_peak); +#endif + cpu_Cas01_im_t cpu = xbt_new0(s_cpu_Cas01_im_t, 1); s_surf_action_cpu_Cas01_im_t action; xbt_assert1(!surf_model_resource_by_name(surf_cpu_model, name), @@ -221,6 +225,12 @@ static void cpu_im_update_remains(cpu_Cas01_im_t cpu, double now) lmm_variable_getvalue(GENERIC_LMM_ACTION (action).variable) * (now - cpu->last_update)); +#ifdef HAVE_TRACING + TRACE_surf_update_action_state (action, action->generic_lmm_action.generic_action.data, + lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable), "PowerUsed", cpu->last_update, now-cpu->last_update); + TRACE_surf_update_action_state_cpu_resource (cpu->generic_resource.name, + action->generic_lmm_action.generic_action.data, lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable), cpu->last_update, now-cpu->last_update); +#endif DEBUG2("Update action(%p) remains %lf", action, GENERIC_ACTION(action).remains); } @@ -299,6 +309,12 @@ static void cpu_im_update_actions_state(double now, double delta) DEBUG1("Action %p: finish", action); GENERIC_ACTION(action).finish = surf_get_clock(); /* set the remains to 0 due to precision problems when updating the remaining amount */ +#ifdef HAVE_TRACING + TRACE_surf_update_action_state (action, action->generic_lmm_action.generic_action.data, + lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable), "PowerUsed", ((cpu_Cas01_im_t)(action->cpu))->last_update, now - ((cpu_Cas01_im_t)(action->cpu))->last_update); + TRACE_surf_update_action_state_cpu_resource (((cpu_Cas01_im_t)(action->cpu))->generic_resource.name, + action->generic_lmm_action.generic_action.data, lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable), ((cpu_Cas01_im_t)(action->cpu))->last_update, now-((cpu_Cas01_im_t)(action->cpu))->last_update); +#endif GENERIC_ACTION(action).remains = 0; cpu_im_cpu_action_state_set((surf_action_t) action, SURF_ACTION_DONE); cpu_im_update_remains(action->cpu, surf_get_clock()); @@ -316,6 +332,9 @@ static void cpu_im_update_resource_state(void *id, cpu->power_scale = value; lmm_update_constraint_bound(cpu_im_maxmin_system, cpu->constraint, cpu->power_scale * cpu->power_peak); +#ifdef HAVE_TRACING + TRACE_surf_cpu_set_power (date, cpu->generic_resource.name, cpu->power_scale * cpu->power_peak); +#endif xbt_swag_insert(cpu, cpu_im_modified_cpu); if (tmgr_trace_event_free(event_type)) cpu->power_event = NULL; diff --git a/src/surf/gtnets/gtnets_simulator.cc b/src/surf/gtnets/gtnets_simulator.cc index 3a8a2f1006..e7a3089618 100644 --- a/src/surf/gtnets/gtnets_simulator.cc +++ b/src/surf/gtnets/gtnets_simulator.cc @@ -322,8 +322,8 @@ Time_t GTSim::get_time_to_next_flow_completion(){ pipe(pfds); t1 = 0; - - if ( (soon_pid=fork()) != 0){ + fflush (NULL); + if( (soon_pid=fork()) != 0){ read(pfds[0], &t1, sizeof(Time_t)); waitpid(soon_pid, &status, 0); }else{ diff --git a/src/surf/network.c b/src/surf/network.c index 2ebad7ff7b..34fa453443 100644 --- a/src/surf/network.c +++ b/src/surf/network.c @@ -56,6 +56,9 @@ static link_CM02_t net_link_new(char *name, xbt_dict_set(surf_network_model->resource_set, name, nw_link, surf_resource_free); +#ifdef HAVE_TRACING + TRACE_surf_net_link_new (name, bw_initial, lat_initial); +#endif return nw_link; } @@ -234,6 +237,20 @@ static void net_update_actions_state(double now, double delta) */ xbt_swag_foreach_safe(action, next_action, running_actions) { + +#ifdef HAVE_TRACING + TRACE_surf_update_action_state (action, action->generic_action.data, + lmm_variable_getvalue(action->variable), "BandwidthUsed", now-delta, delta); + + xbt_dynar_t route = used_routing->get_route(action->src, action->dst); + link_CM02_t link; + unsigned int i; + xbt_dynar_foreach(route, i, link) { + TRACE_surf_update_action_state_net_resource (link->lmm_resource.generic_resource.name, + action->generic_action.data, lmm_variable_getvalue(action->variable), now-delta, delta); + } +#endif + deltap = delta; if (action->latency > 0) { if (action->latency > deltap) { @@ -291,6 +308,9 @@ static void net_update_resource_state(void *id, sg_bandwidth_factor * (nw_link->lmm_resource.power.peak * nw_link->lmm_resource.power.scale)); +#ifdef HAVE_TRACING + TRACE_surf_link_set_bandwidth (date, nw_link->lmm_resource.generic_resource.name, sg_bandwidth_factor * (nw_link->lmm_resource.power.peak * nw_link->lmm_resource.power.scale)); +#endif if (sg_weight_S_parameter > 0) { while ((var = lmm_get_var_from_cnst (network_maxmin_system, nw_link->lmm_resource.constraint, @@ -446,6 +466,10 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name, /* LARGE PLATFORMS HACK: expand also with src->link and dst->link */ + /* saving the src and dst of this communication */ + action->src = src; + action->dst = dst; + XBT_OUT; return (surf_action_t) action; diff --git a/src/surf/network_gtnets.c b/src/surf/network_gtnets.c index ad3d39c602..b549b42456 100644 --- a/src/surf/network_gtnets.c +++ b/src/surf/network_gtnets.c @@ -38,7 +38,9 @@ static void link_new(char *name, double bw, double lat, xbt_dict_t props) gtnets_link->bw_current = bw; gtnets_link->lat_current = lat; gtnets_link->id = link_count; - +#ifdef HAVE_TRACING + TRACE_surf_net_link_new (name, bw, lat); +#endif xbt_dict_set(surf_network_model->resource_set, name, gtnets_link, surf_resource_free); } @@ -231,6 +233,27 @@ static void update_actions_state(double now, double delta) DEBUG2("Action (%p) remains old value: %f", action, action->generic_action.remains); double remain = gtnets_get_flow_rx(action); + +#ifdef HAVE_TRACING + // tracing surf action + TRACE_surf_update_action_state (action, action->generic_action.data, + (action->generic_action.remains-remain)/delta, "BandwidthUsed", now-delta, delta); + + // tracing resource utilization + int src = TRACE_surf_gtnets_get_src (action); + int dst = TRACE_surf_gtnets_get_dst (action); + if (src != -1 && dst != -1){ + xbt_dynar_t route = used_routing->get_route(src, dst); + network_link_GTNETS_t link; + unsigned int i; + xbt_dynar_foreach(route, i, link) { + + TRACE_surf_update_action_state_net_resource (link->generic_resource.name, + action->generic_action.data, (action->generic_action.remains-remain)/delta, now-delta, delta); + } + } +#endif + DEBUG1("Remain value returned by GTNetS : %f", remain); //need to trust this remain value if (remain == 0) { @@ -246,6 +269,9 @@ static void update_actions_state(double now, double delta) action = (surf_action_network_GTNETS_t) (metadata[i]); action->generic_action.finish = now + time_to_next_flow_completion; +#ifdef HAVE_TRACING + TRACE_surf_gtnets_destroy (action); +#endif action_state_set((surf_action_t) action, SURF_ACTION_DONE); DEBUG1("----> Action (%p) just terminated", action); } @@ -287,6 +313,9 @@ static surf_action_t communicate(const char *src_name, const char *dst_name, xbt_assert2(0, "Not route between host %s and host %s", src_name, dst_name); } +#ifdef HAVE_TRACING + TRACE_surf_gtnets_communicate (action, src, dst); +#endif return (surf_action_t) action; } diff --git a/src/surf/network_private.h b/src/surf/network_private.h index d57d9cecff..137203abd1 100644 --- a/src/surf/network_private.h +++ b/src/surf/network_private.h @@ -29,6 +29,9 @@ typedef struct surf_action_network_CM02 { lmm_variable_t variable; double rate; int suspended; + + int src; /* saving source id for tracing */ + int dst; /* saving dest id for tracing */ } s_surf_action_network_CM02_t, *surf_action_network_CM02_t; #endif /* _SURF_NETWORK_PRIVATE_H */ diff --git a/src/surf/surf_private.h b/src/surf/surf_private.h index 1c1ad35625..7d0d1a36a5 100644 --- a/src/surf/surf_private.h +++ b/src/surf/surf_private.h @@ -14,6 +14,7 @@ #include "xbt/log.h" #include "surf/surfxml_parse_private.h" #include "surf/random_mgr.h" +#include "instr/private.h" #define NO_MAX_DURATION -1.0 diff --git a/src/surf/surf_routing.c b/src/surf/surf_routing.c index 1d4972b5ce..0a1f16a2b2 100644 --- a/src/surf/surf_routing.c +++ b/src/surf/surf_routing.c @@ -87,6 +87,9 @@ static void routing_full_parse_Shost(void) { DEBUG2("Seen host %s (#%d)",A_surfxml_host_id,used_routing->host_count); *val = used_routing->host_count++; xbt_dict_set(used_routing->host_id,A_surfxml_host_id,val,xbt_free); +#ifdef HAVE_TRACING + TRACE_surf_define_host_id (A_surfxml_host_id, *val); +#endif } static void routing_full_parse_Srouter(void) { @@ -95,6 +98,10 @@ static void routing_full_parse_Srouter(void) { HOST2ROUTER(used_routing->router_count)); *val = HOST2ROUTER(used_routing->router_count++); xbt_dict_set(used_routing->host_id,A_surfxml_router_id,val,xbt_free); +#ifdef HAVE_TRACING + TRACE_surf_define_host_id (A_surfxml_host_id, *val); + TRACE_surf_cpu_new (A_surfxml_host_id, 0); +#endif } static int src_id = -1; @@ -310,6 +317,9 @@ static void routing_full_parse_end(void) { new_link->link_ptr = xbt_dict_get_or_null(surf_network_model->resource_set, link_name); DEBUG3("Adding onelink route from (#%d) to (#%d), link_name %s",src_id, dst_id, link_name); xbt_dict_set(onelink_routes, link_name, (void *)new_link, onelink_route_elem_free); +#ifdef HAVE_TRACING + TRACE_surf_routing_full_parse_end (link_name, src_id, dst_id); +#endif } if(ISROUTER(src_id) || ISROUTER(dst_id)) {