Show the latency histograms by IP address rather than by trace
[lttv.git] / lttv / lttv / sync / sync_chain_lttv.c
index 399b79628221c7446cf5f2637e01ccc2b3beff0f..4a70154884a63a59ac703abecc95dca5753a6c76 100644 (file)
@@ -33,7 +33,7 @@
 #include <lttv/module.h>
 #include <lttv/option.h>
 
-#include "sync_chain_lttv.h"
+#include "sync_chain.h"
 
 
 #ifndef g_info
@@ -45,19 +45,51 @@ static void init();
 static void destroy();
 
 static void gfAppendAnalysisName(gpointer data, gpointer user_data);
-
-static gboolean optionSync;
-static gboolean optionSyncStats;
-static gboolean optionSyncNull;
-static char* optionSyncAnalysis;
-static gboolean optionSyncGraphs;
-static char* optionSyncGraphsDir;
-static char graphsDir[20];
+static void gfAddModuleOption(gpointer data, gpointer user_data);
+static void gfRemoveModuleOption(gpointer data, gpointer user_data);
 
 GQueue processingModules= G_QUEUE_INIT;
 GQueue matchingModules= G_QUEUE_INIT;
 GQueue analysisModules= G_QUEUE_INIT;
-
+GQueue moduleOptions= G_QUEUE_INIT;
+
+static char* argHelpNone= "none";
+static ModuleOption optionSync= {
+       .longName= "sync",
+       .hasArg= NO_ARG,
+       {.present= false},
+       .optionHelp= "synchronize the time between the traces",
+};
+static char graphsDir[20];
+static ModuleOption optionSyncStats= {
+       .longName= "sync-stats",
+       .hasArg= NO_ARG,
+       {.present= false},
+       .optionHelp= "print statistics about the time synchronization",
+};
+static ModuleOption optionSyncNull= {
+       .longName= "sync-null",
+       .hasArg= NO_ARG,
+       {.present= false},
+       .optionHelp= "read the events but do not perform any processing",
+};
+static GString* analysisModulesNames;
+static ModuleOption optionSyncAnalysis= {
+       .longName= "sync-analysis",
+       .hasArg= REQUIRED_ARG,
+       .optionHelp= "specify the algorithm to use for event analysis",
+};
+static ModuleOption optionSyncGraphs= {
+       .longName= "sync-graphs",
+       .hasArg= NO_ARG,
+       {.present= false},
+       .optionHelp= "output gnuplot graph showing synchronization points",
+};
+static ModuleOption optionSyncGraphsDir= {
+       .longName= "sync-graphs-dir",
+       .hasArg= REQUIRED_ARG,
+       .optionHelp= "specify the directory where to store the graphs",
+};
 
 /*
  * Module init function
@@ -72,51 +104,37 @@ GQueue analysisModules= G_QUEUE_INIT;
  */
 static void init()
 {
-       GString* analysisModulesNames;
        int retval;
 
        g_debug("\t\t\tXXXX sync init\n");
 
-       optionSync= FALSE;
-       lttv_option_add("sync", '\0', "synchronize the time between the traces" ,
-               "none", LTTV_OPT_NONE, &optionSync, NULL, NULL);
-
-       optionSyncStats= FALSE;
-       lttv_option_add("sync-stats", '\0', "print statistics about the time "
-               "synchronization", "none", LTTV_OPT_NONE, &optionSyncStats, NULL,
-               NULL);
-
-       optionSyncNull= FALSE;
-       lttv_option_add("sync-null", '\0', "read the events but do not perform "
-               "any processing", "none", LTTV_OPT_NONE, &optionSyncNull, NULL, NULL);
-
        g_assert(g_queue_get_length(&analysisModules) > 0);
-       optionSyncAnalysis= ((AnalysisModule*)
+       optionSyncAnalysis.arg = ((AnalysisModule*)
                g_queue_peek_head(&analysisModules))->name;
        analysisModulesNames= g_string_new("");
        g_queue_foreach(&analysisModules, &gfAppendAnalysisName,
                analysisModulesNames);
        // remove the last ", "
        g_string_truncate(analysisModulesNames, analysisModulesNames->len - 2);
-       lttv_option_add("sync-analysis", '\0', "specify the algorithm to use for "
-               "event analysis" , analysisModulesNames->str, LTTV_OPT_STRING,
-               &optionSyncAnalysis, NULL, NULL);
-       g_string_free(analysisModulesNames, TRUE);
-
-       optionSyncGraphs= FALSE;
-       lttv_option_add("sync-graphs", '\0', "output gnuplot graph showing "
-               "synchronization points", "none", LTTV_OPT_NONE, &optionSyncGraphs,
-               NULL, NULL);
+       optionSyncAnalysis.argHelp= analysisModulesNames->str;
 
        retval= snprintf(graphsDir, sizeof(graphsDir), "graphs-%d", getpid());
        if (retval > sizeof(graphsDir) - 1)
        {
                graphsDir[sizeof(graphsDir) - 1]= '\0';
        }
-       optionSyncGraphsDir= graphsDir;
-       lttv_option_add("sync-graphs-dir", '\0', "specify the directory where to"
-               " store the graphs", graphsDir, LTTV_OPT_STRING, &optionSyncGraphsDir,
-               NULL, NULL);
+       optionSyncGraphsDir.arg= graphsDir;
+       optionSyncGraphsDir.argHelp= graphsDir;
+
+       g_queue_push_head(&moduleOptions, &optionSyncGraphsDir);
+       g_queue_push_head(&moduleOptions, &optionSyncGraphs);
+       g_queue_push_head(&moduleOptions, &optionSyncAnalysis);
+       g_queue_push_head(&moduleOptions, &optionSyncNull);
+       g_queue_push_head(&moduleOptions, &optionSyncStats);
+       g_queue_push_head(&moduleOptions, &optionSync);
+
+       g_queue_foreach(&moduleOptions, &gfAddModuleOption, NULL);
+
 }
 
 
@@ -127,12 +145,13 @@ static void destroy()
 {
        g_debug("\t\t\tXXXX sync destroy\n");
 
-       lttv_option_remove("sync");
-       lttv_option_remove("sync-stats");
-       lttv_option_remove("sync-null");
-       lttv_option_remove("sync-analysis");
-       lttv_option_remove("sync-graphs");
-       lttv_option_remove("sync-graphs-dir");
+       g_queue_foreach(&moduleOptions, &gfRemoveModuleOption, NULL);
+       g_string_free(analysisModulesNames, TRUE);
+
+       g_queue_clear(&processingModules);
+       g_queue_clear(&matchingModules);
+       g_queue_clear(&analysisModules);
+       g_queue_clear(&moduleOptions);
 }
 
 
@@ -150,16 +169,16 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
        struct timeval startTime, endTime;
        struct rusage startUsage, endUsage;
        GList* result;
-       FILE* graphsStream;
+       unsigned int i, j;
        int retval;
 
-       if (optionSync == FALSE)
+       if (!optionSync.present)
        {
                g_debug("Not synchronizing traceset because option is disabled");
                return;
        }
 
-       if (optionSyncStats)
+       if (optionSyncStats.present)
        {
                gettimeofday(&startTime, 0);
                getrusage(RUSAGE_SELF, &startUsage);
@@ -169,7 +188,7 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
        syncState= malloc(sizeof(SyncState));
        syncState->traceNb= lttv_traceset_number(traceSetContext->ts);
 
-       if (optionSyncStats)
+       if (optionSyncStats.present)
        {
                syncState->stats= true;
        }
@@ -178,40 +197,15 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
                syncState->stats= false;
        }
 
-       if (optionSyncGraphs)
-       {
-               syncState->graphs= optionSyncGraphsDir;
-       }
-       else
-       {
-               syncState->graphs= NULL;
-       }
-
-       // Identify and initialize processing module
-       syncState->processingData= NULL;
-       if (optionSyncNull)
-       {
-               result= g_queue_find_custom(&processingModules, "LTTV-null",
-                       &gcfCompareProcessing);
-       }
-       else
-       {
-               result= g_queue_find_custom(&processingModules, "LTTV-standard",
-                       &gcfCompareProcessing);
-       }
-       g_assert(result != NULL);
-       syncState->processingModule= (ProcessingModule*) result->data;
-
-       graphsStream= NULL;
-       if (syncState->graphs &&
-               syncState->processingModule->writeProcessingGraphsPlots != NULL)
+       if (optionSyncGraphs.present)
        {
                char* cwd;
                int graphsFp;
 
                // Create the graph directory right away in case the module initialization
                // functions have something to write in it.
-               cwd= changeToGraphDir(syncState->graphs);
+               syncState->graphsDir= optionSyncGraphsDir.arg;
+               cwd= changeToGraphDir(optionSyncGraphsDir.arg);
 
                if ((graphsFp= open("graphs.gnu", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
                                S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
@@ -219,11 +213,15 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
                {
                        g_error(strerror(errno));
                }
-               if ((graphsStream= fdopen(graphsFp, "w")) == NULL)
+               if ((syncState->graphsStream= fdopen(graphsFp, "w")) == NULL)
                {
                        g_error(strerror(errno));
                }
 
+               fprintf(syncState->graphsStream,
+                       "#!/usr/bin/gnuplot\n\n"
+                       "set terminal postscript eps color size 8in,6in\n");
+
                retval= chdir(cwd);
                if (retval == -1)
                {
@@ -231,13 +229,34 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
                }
                free(cwd);
        }
+       else
+       {
+               syncState->graphsStream= NULL;
+               syncState->graphsDir= NULL;
+       }
 
-       // Identify matching and analysis modules
+       // Identify and initialize modules
+       syncState->processingData= NULL;
+       if (optionSyncNull.present)
+       {
+               result= g_queue_find_custom(&processingModules, "LTTV-null",
+                       &gcfCompareProcessing);
+       }
+       else
+       {
+               result= g_queue_find_custom(&processingModules, "LTTV-standard",
+                       &gcfCompareProcessing);
+       }
+       g_assert(result != NULL);
+       syncState->processingModule= (ProcessingModule*) result->data;
+
+       syncState->matchingData= NULL;
        result= g_queue_find_custom(&matchingModules, "TCP", &gcfCompareMatching);
        g_assert(result != NULL);
        syncState->matchingModule= (MatchingModule*) result->data;
 
-       result= g_queue_find_custom(&analysisModules, optionSyncAnalysis,
+       syncState->analysisData= NULL;
+       result= g_queue_find_custom(&analysisModules, optionSyncAnalysis.arg,
                &gcfCompareAnalysis);
        if (result != NULL)
        {
@@ -245,19 +264,15 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
        }
        else
        {
-               g_error("Analysis module '%s' not found", optionSyncAnalysis);
+               g_error("Analysis module '%s' not found", optionSyncAnalysis.arg);
        }
 
-       syncState->processingModule->initProcessing(syncState, traceSetContext);
-
-       syncState->matchingData= NULL;
-       syncState->analysisData= NULL;
-
-       if (!optionSyncNull)
+       if (!optionSyncNull.present)
        {
-               syncState->matchingModule->initMatching(syncState);
                syncState->analysisModule->initAnalysis(syncState);
+               syncState->matchingModule->initMatching(syncState);
        }
+       syncState->processingModule->initProcessing(syncState, traceSetContext);
 
        // Process traceset
        lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero);
@@ -268,58 +283,87 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
        syncState->processingModule->finalizeProcessing(syncState);
 
        // Write graphs file
-       if (graphsStream != NULL)
+       if (optionSyncGraphs.present)
        {
-               unsigned int i, j;
-
-               fprintf(graphsStream,
-                       "#!/usr/bin/gnuplot\n\n"
-                       "set terminal postscript eps color size 8in,6in\n");
-
                // Cover the upper triangular matrix, i is the reference node.
                for (i= 0; i < syncState->traceNb; i++)
                {
                        for (j= i + 1; j < syncState->traceNb; j++)
                        {
-                               long pos;
+                               long pos1, pos2, trunc;
 
-                               fprintf(graphsStream,
-                                       "\nset output \"%03d-%03d.eps\"\n"
+                               fprintf(syncState->graphsStream,
+                                       "\nreset\n"
+                                       "set output \"%03d-%03d.eps\"\n"
                                        "plot \\\n", i, j);
 
-                               syncState->processingModule->writeProcessingGraphsPlots(graphsStream,
-                                       syncState, i, j);
+                               if (syncState->processingModule->writeProcessingGraphsPlots)
+                               {
+                                       syncState->processingModule->writeProcessingGraphsPlots(syncState,
+                                               i, j);
+                               }
+                               if (syncState->matchingModule->writeMatchingGraphsPlots)
+                               {
+                                       syncState->matchingModule->writeMatchingGraphsPlots(syncState,
+                                               i, j);
+                               }
+                               if (syncState->analysisModule->writeAnalysisGraphsPlots)
+                               {
+                                       syncState->analysisModule->writeAnalysisGraphsPlots(syncState,
+                                               i, j);
+                               }
 
-                               // Remove the ", \\\n" from the last graph plot line
-                               fflush(graphsStream);
-                               pos= ftell(graphsStream);
-                               if (ftruncate(fileno(graphsStream), pos - 4) == -1)
+                               fflush(syncState->graphsStream);
+                               pos2= ftell(syncState->graphsStream);
+                               if (pos1 != pos2)
+                               {
+                                       // Remove the ", \\\n" from the last graph plot line
+                                       trunc= pos2 - 4;
+                               }
+                               else
+                               {
+                                       // Remove the "plot \\\n" line to avoid creating an invalid
+                                       // gnuplot script
+                                       trunc= pos2 - 7;
+                               }
+
+                               if (ftruncate(fileno(syncState->graphsStream), trunc) == -1)
                                {
                                        g_error(strerror(errno));
                                }
-                               if (fseek(graphsStream, 0, SEEK_END) == -1)
+                               if (fseek(syncState->graphsStream, 0, SEEK_END) == -1)
                                {
                                        g_error(strerror(errno));
                                }
 
-                               fprintf(graphsStream,
-                                       "\nset output \"%1$03d-%2$03d.eps\"\n"
-                                       "set key inside right bottom\n"
-                                       "set title \"\"\n"
-                                       "set xlabel \"Clock %1$u\"\n"
-                                       "set xtics nomirror\n"
-                                       "set ylabel \"Clock %2$u\"\n"
-                                       "set ytics nomirror\n", i, j);
+                               fprintf(syncState->graphsStream,
+                                       "\nset output \"%03d-%03d.eps\"\n"
+                                       "set title \"\"\n", i, j);
 
-                               syncState->processingModule->writeProcessingGraphsOptions(graphsStream,
-                                       syncState, i, j);
+                               if (syncState->processingModule->writeProcessingGraphsOptions)
+                               {
+                                       syncState->processingModule->writeProcessingGraphsOptions(syncState,
+                                               i, j);
+                               }
+                               if (syncState->matchingModule->writeMatchingGraphsOptions)
+                               {
+                                       syncState->matchingModule->writeMatchingGraphsOptions(syncState,
+                                               i, j);
+                               }
+                               if (syncState->analysisModule->writeAnalysisGraphsOptions)
+                               {
+                                       syncState->analysisModule->writeAnalysisGraphsOptions(syncState,
+                                               i, j);
+                               }
 
-                               fprintf(graphsStream,
-                                       "replot\n");
+                               if (pos1 != pos2)
+                               {
+                                       fprintf(syncState->graphsStream, "replot\n");
+                               }
                        }
                }
 
-               if (fclose(graphsStream) != 0)
+               if (fclose(syncState->graphsStream) != 0)
                {
                        g_error(strerror(errno));
                }
@@ -329,6 +373,31 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
        {
                syncState->processingModule->printProcessingStats(syncState);
        }
+       if (syncState->matchingModule->printMatchingStats != NULL)
+       {
+               syncState->matchingModule->printMatchingStats(syncState);
+       }
+       if (syncState->analysisModule->printAnalysisStats != NULL)
+       {
+               syncState->analysisModule->printAnalysisStats(syncState);
+       }
+
+       if (optionSyncStats.present)
+       {
+               printf("Resulting synchronization factors:\n");
+               for (i= 0; i < syncState->traceNb; i++)
+               {
+                       LttTrace* t;
+
+                       t= traceSetContext->traces[i]->t;
+
+                       printf("\ttrace %u drift= %g offset= %g (%f) start time= %ld.%09ld\n",
+                               i, t->drift, t->offset, (double) tsc_to_uint64(t->freq_scale,
+                                       t->start_freq, t->offset) / NANOSECONDS_PER_SECOND,
+                               t->start_time_from_tsc.tv_sec,
+                               t->start_time_from_tsc.tv_nsec);
+               }
+       }
 
        syncState->processingModule->destroyProcessing(syncState);
        if (syncState->matchingModule != NULL)
@@ -342,7 +411,7 @@ void syncTraceset(LttvTracesetContext* const traceSetContext)
 
        free(syncState);
 
-       if (optionSyncStats)
+       if (optionSyncStats.present)
        {
                gettimeofday(&endTime, 0);
                retval= getrusage(RUSAGE_SELF, &endUsage);
@@ -478,7 +547,7 @@ static void gfAppendAnalysisName(gpointer data, gpointer user_data)
  *   The current working directory before the execution of the function. The
  *   string must be free'd by the caller.
  */
-char* changeToGraphDir(char* const graphs)
+char* changeToGraphDir(const char* const graphs)
 {
        int retval;
        char* cwd;
@@ -509,6 +578,43 @@ char* changeToGraphDir(char* const graphs)
 }
 
 
+/*
+ * A GFunc for g_queue_foreach()
+ *
+ * Args:
+ *   data:         ModuleOption*
+ *   user_data:    NULL
+ */
+static void gfAddModuleOption(gpointer data, gpointer user_data)
+{
+       ModuleOption* option;
+       LttvOptionType conversion[]= {
+               [NO_ARG]= LTTV_OPT_NONE,
+               [REQUIRED_ARG]= LTTV_OPT_STRING,
+       };
+
+       g_assert_cmpuint(sizeof(conversion) / sizeof(*conversion), ==,
+               HAS_ARG_COUNT);
+       option= (ModuleOption*) data;
+       lttv_option_add(option->longName, '\0', option->optionHelp,
+               option->argHelp ? option->argHelp : argHelpNone,
+               conversion[option->hasArg], &option->arg, NULL, NULL);
+}
+
+
+/*
+ * A GFunc for g_queue_foreach()
+ *
+ * Args:
+ *   data:         ModuleOption*
+ *   user_data:    NULL
+ */
+static void gfRemoveModuleOption(gpointer data, gpointer user_data)
+{
+       lttv_option_remove(((ModuleOption*) data)->longName);
+}
+
+
 LTTV_MODULE("sync", "Synchronize traces", \
        "Synchronizes a traceset based on the correspondance of network events", \
        init, destroy, "option")
This page took 0.029368 seconds and 4 git commands to generate.