From: Benjamin Poirier Date: Mon, 16 Nov 2009 22:04:54 +0000 (-0500) Subject: Store graph callbacks in a structure X-Git-Tag: v0.12.26~33 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=467066eeab8b0a4e5ea07d24f1840310730fd470;p=lttv.git Store graph callbacks in a structure Also support two classes of graphs: with "trace-trace" scale (both axes present timestamp data); with "trace-time" scale (horizontal axis presents timestamp data, vertical axis presents difference between timstamps) Signed-off-by: Benjamin Poirier --- diff --git a/lttv/lttv/Makefile.am b/lttv/lttv/Makefile.am index 791bf989..10729886 100644 --- a/lttv/lttv/Makefile.am +++ b/lttv/lttv/Makefile.am @@ -56,6 +56,7 @@ lttv_real_SOURCES = \ filter.c\ print.c\ sync/sync_chain_lttv.c\ + sync/graph_functions.c\ sync/data_structures.c\ sync/event_processing_lttng_common.c\ sync/event_processing_lttng_standard.c\ diff --git a/lttv/lttv/sync/data_structures.h b/lttv/lttv/sync/data_structures.h index 5f5e4be3..014b7da1 100644 --- a/lttv/lttv/sync/data_structures.h +++ b/lttv/lttv/sync/data_structures.h @@ -86,6 +86,8 @@ typedef struct typedef struct _Event { unsigned long traceNum; + // wallTime is corrected according to factors in trace struct, cpuTime + // is not uint64_t cpuTime; WallTime wallTime; diff --git a/lttv/lttv/sync/event_analysis.h b/lttv/lttv/sync/event_analysis.h index 0a32fe1c..4c89aca9 100644 --- a/lttv/lttv/sync/event_analysis.h +++ b/lttv/lttv/sync/event_analysis.h @@ -23,6 +23,7 @@ #include #include "data_structures.h" +#include "graph_functions.h" struct _SyncState; @@ -41,11 +42,9 @@ typedef struct void (*analyzeBroadcast)(struct _SyncState* const syncState, Broadcast* const broadcast); GArray* (*finalizeAnalysis)(struct _SyncState* const syncState); + void (*printAnalysisStats)(struct _SyncState* const syncState); - void (*writeAnalysisGraphsPlots)(struct _SyncState* const syncState, const - unsigned int i, const unsigned int j); - void (*writeAnalysisGraphsOptions)(struct _SyncState* const syncState, - const unsigned int i, const unsigned int j); + GraphFunctions graphFunctions; } AnalysisModule; #endif diff --git a/lttv/lttv/sync/event_analysis_chull.c b/lttv/lttv/sync/event_analysis_chull.c index 1dc995b1..25736018 100644 --- a/lttv/lttv/sync/event_analysis_chull.c +++ b/lttv/lttv/sync/event_analysis_chull.c @@ -108,12 +108,11 @@ static AnalysisModule analysisModuleCHull= { .initAnalysis= &initAnalysisCHull, .destroyAnalysis= &destroyAnalysisCHull, .analyzeMessage= &analyzeMessageCHull, - .analyzeExchange= NULL, - .analyzeBroadcast= NULL, .finalizeAnalysis= &finalizeAnalysisCHull, .printAnalysisStats= &printAnalysisStatsCHull, - .writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsCHull, - .writeAnalysisGraphsOptions= NULL, + .graphFunctions= { + .writeTraceTracePlots= &writeAnalysisGraphsPlotsCHull, + } }; diff --git a/lttv/lttv/sync/event_analysis_eval.c b/lttv/lttv/sync/event_analysis_eval.c index dd831087..223a75b8 100644 --- a/lttv/lttv/sync/event_analysis_eval.c +++ b/lttv/lttv/sync/event_analysis_eval.c @@ -77,6 +77,7 @@ static void hitBin(struct Bins* const bins, const double value); static unsigned int binNum(const double value) __attribute__((pure)); static double binStart(const unsigned int binNum) __attribute__((pure)); static double binEnd(const unsigned int binNum) __attribute__((pure)); +static uint32_t normalTotal(struct Bins* const bins) __attribute__((const)); static AnalysisGraphEval* constructAnalysisGraphEval(const char* const graphsDir, const struct RttKey* const rttKey); @@ -85,7 +86,7 @@ static void gdnDestroyAnalysisGraphEval(gpointer data); static void ghfWriteGraph(gpointer key, gpointer value, gpointer user_data); static void dumpBinToFile(const struct Bins* const bins, FILE* const file); static void writeHistogram(FILE* graphsStream, const struct RttKey* rttKey, - double* minRtt); + double* minRtt, AnalysisGraphEval* const graph); double binBase; @@ -99,8 +100,6 @@ static AnalysisModule analysisModuleEval= { .analyzeBroadcast= &analyzeBroadcastEval, .finalizeAnalysis= &finalizeAnalysisEval, .printAnalysisStats= &printAnalysisStatsEval, - .writeAnalysisGraphsPlots= NULL, - .writeAnalysisGraphsOptions= NULL, }; static ModuleOption optionEvalRttFile= { @@ -326,7 +325,7 @@ static void ghfWriteGraph(gpointer key, gpointer value, gpointer user_data) dumpBinToFile(&graph->ttSendBins, graph->ttSendPoints); dumpBinToFile(&graph->ttRecvBins, graph->ttRecvPoints); dumpBinToFile(&graph->hrttBins, graph->hrttPoints); - writeHistogram(info->graphsStream, rttKey, rtt1); + writeHistogram(info->graphsStream, rttKey, rtt1, graph); } @@ -361,9 +360,11 @@ static void dumpBinToFile(const struct Bins* const bins, FILE* const file) * graphsStream: write to this file * rttKey: must be sorted such that saddr < daddr * minRtt: if available, else NULL + * graph: struct that contains the bins for the pair of traces + * identified by rttKey */ static void writeHistogram(FILE* graphsStream, const struct RttKey* rttKey, - double* minRtt) + double* minRtt, AnalysisGraphEval* const graph) { char saddr[16], daddr[16]; @@ -381,20 +382,53 @@ static void writeHistogram(FILE* graphsStream, const struct RttKey* rttKey, { fprintf(graphsStream, "set arrow from %.9f, 0 rto 0, graph 1 " - "nohead linetype 3 linewidth 3 linecolor rgb \"black\"\n", *minRtt / 2); + "nohead linetype 3 linewidth 3 linecolor rgb \"black\"\n", *minRtt + / 2); } - fprintf(graphsStream, - "plot \\\n" - "\t\"analysis_eval_hrtt-%1$s_and_%2$s.data\" " - "title \"RTT/2\" with linespoints linetype 1 linewidth 2 " - "linecolor rgb \"black\" pointtype 6 pointsize 1,\\\n" - "\t\"analysis_eval_tt-%1$s_to_%2$s.data\" " - "title \"%1$s to %2$s\" with linespoints linetype 4 linewidth 2 " - "linecolor rgb \"gray60\" pointtype 6 pointsize 1,\\\n" - "\t\"analysis_eval_tt-%2$s_to_%1$s.data\" " - "title \"%2$s to %1$s\" with linespoints linetype 4 linewidth 2 " - "linecolor rgb \"gray30\" pointtype 6 pointsize 1\n", saddr, daddr); + if (normalTotal(&graph->ttSendBins) || normalTotal(&graph->ttRecvBins) || + normalTotal(&graph->hrttBins)) + { + fprintf(graphsStream, "plot \\\n"); + + if (normalTotal(&graph->hrttBins)) + { + fprintf(graphsStream, + "\t\"analysis_eval_hrtt-%s_and_%s.data\" " + "title \"RTT/2\" with linespoints linetype 1 linewidth 2 " + "linecolor rgb \"black\" pointtype 6 pointsize 1,\\\n", + saddr, daddr); + } + + if (normalTotal(&graph->ttSendBins)) + { + fprintf(graphsStream, + "\t\"analysis_eval_tt-%1$s_to_%2$s.data\" " + "title \"%1$s to %2$s\" with linespoints linetype 4 linewidth 2 " + "linecolor rgb \"gray60\" pointtype 6 pointsize 1,\\\n", + saddr, daddr); + } + + if (normalTotal(&graph->ttRecvBins)) + { + fprintf(graphsStream, + "\t\"analysis_eval_tt-%1$s_to_%2$s.data\" " + "title \"%1$s to %2$s\" with linespoints linetype 4 linewidth 2 " + "linecolor rgb \"gray30\" pointtype 6 pointsize 1,\\\n", + daddr, saddr); + } + + // Remove the ",\\\n" from the last graph plot line + if (ftruncate(fileno(graphsStream), ftell(graphsStream) - 3) == -1) + { + g_error(strerror(errno)); + } + if (fseek(graphsStream, 0, SEEK_END) == -1) + { + g_error(strerror(errno)); + } + fprintf(graphsStream, "\n"); + } } @@ -706,7 +740,7 @@ static void printAnalysisStatsEval(SyncState* const syncState) { printf("\tsum of broadcast differential delays: %g\n", analysisData->stats->broadcastDiffSum); - printf("\taverage broadcast differential delays: %g\n", + printf("\taverage broadcast differential delay: %g\n", analysisData->stats->broadcastDiffSum / analysisData->stats->broadcastNb); } @@ -1185,3 +1219,16 @@ static double binEnd(const unsigned int binNum) return INFINITY; } } + + +/* + * Return the total number of elements in the "normal" bins (not underflow or + * overflow) + * + * Args: + * bins: the structure containing bins to build a histrogram + */ +static uint32_t normalTotal(struct Bins* const bins) +{ + return bins->total - bins->bin[0] - bins->bin[BIN_NB - 1]; +} diff --git a/lttv/lttv/sync/event_analysis_linreg.c b/lttv/lttv/sync/event_analysis_linreg.c index 3e88c71c..a79559e6 100644 --- a/lttv/lttv/sync/event_analysis_linreg.c +++ b/lttv/lttv/sync/event_analysis_linreg.c @@ -71,13 +71,12 @@ static AnalysisModule analysisModuleLinReg= { .name= "linreg", .initAnalysis= &initAnalysisLinReg, .destroyAnalysis= &destroyAnalysisLinReg, - .analyzeMessage= NULL, .analyzeExchange= &analyzeExchangeLinReg, - .analyzeBroadcast= NULL, .finalizeAnalysis= &finalizeAnalysisLinReg, .printAnalysisStats= &printAnalysisStatsLinReg, - .writeAnalysisGraphsPlots= &writeAnalysisGraphsPlotsLinReg, - .writeAnalysisGraphsOptions= NULL, + .graphFunctions= { + .writeTraceTracePlots= &writeAnalysisGraphsPlotsLinReg, + } }; diff --git a/lttv/lttv/sync/event_matching.h b/lttv/lttv/sync/event_matching.h index 103d8138..28839f20 100644 --- a/lttv/lttv/sync/event_matching.h +++ b/lttv/lttv/sync/event_matching.h @@ -22,7 +22,7 @@ #include #include "data_structures.h" - +#include "graph_functions.h" struct _SyncState; @@ -37,11 +37,9 @@ typedef struct void (*matchEvent)(struct _SyncState* const syncState, Event* const event); GArray* (*finalizeMatching)(struct _SyncState* const syncState); + void (*printMatchingStats)(struct _SyncState* const syncState); - void (*writeMatchingGraphsPlots)(struct _SyncState* const syncState, const - unsigned int i, const unsigned int j); - void (*writeMatchingGraphsOptions)(struct _SyncState* const syncState, - const unsigned int i, const unsigned int j); + GraphFunctions graphFunctions; } MatchingModule; #endif diff --git a/lttv/lttv/sync/event_matching_broadcast.c b/lttv/lttv/sync/event_matching_broadcast.c index 98bab58a..3006f404 100644 --- a/lttv/lttv/sync/event_matching_broadcast.c +++ b/lttv/lttv/sync/event_matching_broadcast.c @@ -67,8 +67,9 @@ static MatchingModule matchingModuleBroadcast = { .matchEvent= &matchEventBroadcast, .finalizeMatching= &finalizeMatchingBroadcast, .printMatchingStats= &printMatchingStatsBroadcast, - .writeMatchingGraphsPlots= &writeMatchingGraphsPlotsBroadcast, - .writeMatchingGraphsOptions= NULL, + .graphFunctions= { + .writeTraceTimePlots= &writeMatchingGraphsPlotsBroadcast, + } }; @@ -430,8 +431,8 @@ static void writeAccuracyPoints(MatchingGraphsBroadcast* graphs, const if (eventI->traceNum < eventJ->traceNum) { fprintf(graphs->accuracyPoints[eventJ->traceNum][eventI->traceNum], - "%20llu %20lld\n", eventI->cpuTime, (int64_t) eventJ->cpuTime - - eventI->cpuTime); + "%20llu %20.9f\n", eventI->cpuTime, + wallTimeSub(&eventJ->wallTime, &eventI->wallTime)); graphs->pointsNb[eventJ->traceNum][eventI->traceNum]++; } } diff --git a/lttv/lttv/sync/event_matching_distributor.c b/lttv/lttv/sync/event_matching_distributor.c index 2735f22f..9eeaff7c 100644 --- a/lttv/lttv/sync/event_matching_distributor.c +++ b/lttv/lttv/sync/event_matching_distributor.c @@ -54,10 +54,14 @@ static void matchEventDistributor(SyncState* const syncState, Event* const event); static GArray* finalizeMatchingDistributor(SyncState* const syncState); static void printMatchingStatsDistributor(SyncState* const syncState); -static void writeMatchingGraphsPlotsDistributor(SyncState* const syncState, - const unsigned int i, const unsigned int j); -static void writeMatchingGraphsOptionsDistributor(SyncState* const syncState, - const unsigned int i, const unsigned int j); +static void writeMatchingTraceTracePlotsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j); +static void writeMatchingTraceTraceOptionsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j); +static void writeMatchingTraceTimePlotsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j); +static void writeMatchingTraceTimeOptionsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j); // Functions specific to this module static void registerMatchingDistributor() __attribute__((constructor (101))); @@ -79,8 +83,12 @@ static MatchingModule matchingModuleDistributor = { .matchEvent= &matchEventDistributor, .finalizeMatching= &finalizeMatchingDistributor, .printMatchingStats= &printMatchingStatsDistributor, - .writeMatchingGraphsPlots= &writeMatchingGraphsPlotsDistributor, - .writeMatchingGraphsOptions= &writeMatchingGraphsOptionsDistributor, + .graphFunctions= { + .writeTraceTracePlots= &writeMatchingTraceTracePlotsDistributor, + .writeTraceTraceOptions= &writeMatchingTraceTraceOptionsDistributor, + .writeTraceTimePlots= &writeMatchingTraceTimePlotsDistributor, + .writeTraceTimeOptions= &writeMatchingTraceTimeOptionsDistributor, + }, }; @@ -210,14 +218,52 @@ static void printMatchingStatsDistributor(SyncState* const syncState) * i: first trace number * j: second trace number, garanteed to be larger than i */ -static void writeMatchingGraphsPlotsDistributor(SyncState* const syncState, +static void writeMatchingTraceTracePlotsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j) +{ + MatchingDataDistributor* matchingData= syncState->matchingData; + + g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, + &(struct GraphAggregate) {offsetof(MatchingModule, + graphFunctions.writeTraceTracePlots), i, j}); +} + + +/* + * Call the distributed graph lines functions (when they exist). + * + * Args: + * syncState: container for synchronization data + * i: first trace number + * j: second trace number, garanteed to be larger than i + */ +static void writeMatchingTraceTimePlotsDistributor(SyncState* const + syncState, const unsigned int i, const unsigned int j) +{ + MatchingDataDistributor* matchingData= syncState->matchingData; + + g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, + &(struct GraphAggregate) {offsetof(MatchingModule, + graphFunctions.writeTraceTimePlots), i, j}); +} + + +/* + * Call the distributed graph options functions (when they exist). + * + * Args: + * syncState: container for synchronization data + * i: first trace number + * j: second trace number, garanteed to be larger than i + */ +static void writeMatchingTraceTraceOptionsDistributor(SyncState* const syncState, const unsigned int i, const unsigned int j) { MatchingDataDistributor* matchingData= syncState->matchingData; g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, &(struct GraphAggregate) {offsetof(MatchingModule, - writeMatchingGraphsPlots), i, j}); + graphFunctions.writeTraceTraceOptions), i, j}); } @@ -229,14 +275,14 @@ static void writeMatchingGraphsPlotsDistributor(SyncState* const syncState, * i: first trace number * j: second trace number, garanteed to be larger than i */ -static void writeMatchingGraphsOptionsDistributor(SyncState* const syncState, +static void writeMatchingTraceTimeOptionsDistributor(SyncState* const syncState, const unsigned int i, const unsigned int j) { MatchingDataDistributor* matchingData= syncState->matchingData; g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, &(struct GraphAggregate) {offsetof(MatchingModule, - writeMatchingGraphsOptions), i, j}); + graphFunctions.writeTraceTimeOptions), i, j}); } diff --git a/lttv/lttv/sync/event_matching_tcp.c b/lttv/lttv/sync/event_matching_tcp.c index 3bfe479e..f7692212 100644 --- a/lttv/lttv/sync/event_matching_tcp.c +++ b/lttv/lttv/sync/event_matching_tcp.c @@ -74,8 +74,9 @@ static MatchingModule matchingModuleTCP = { .matchEvent= &matchEventTCP, .finalizeMatching= &finalizeMatchingTCP, .printMatchingStats= &printMatchingStatsTCP, - .writeMatchingGraphsPlots= &writeMatchingGraphsPlotsTCP, - .writeMatchingGraphsOptions= NULL, + .graphFunctions= { + .writeTraceTracePlots= &writeMatchingGraphsPlotsTCP, + } }; diff --git a/lttv/lttv/sync/event_processing.h b/lttv/lttv/sync/event_processing.h index 18642408..d1ac7647 100644 --- a/lttv/lttv/sync/event_processing.h +++ b/lttv/lttv/sync/event_processing.h @@ -25,6 +25,7 @@ #include #include "data_structures.h" +#include "graph_functions.h" struct _SyncState; @@ -40,15 +41,7 @@ typedef struct void (*finalizeProcessing)(struct _SyncState* const syncState); void (*printProcessingStats)(struct _SyncState* const syncState); - - /* The processing module must provide the next function if it wishes - * graphs to be created at all. If it provides the next function, it must - * also provide the second next function. - */ - void (*writeProcessingGraphsPlots)(struct _SyncState* const syncState, - const unsigned int i, const unsigned int j); - void (*writeProcessingGraphsOptions)(struct _SyncState* const syncState, - const unsigned int i, const unsigned int j); + GraphFunctions graphFunctions; } ProcessingModule; #endif diff --git a/lttv/lttv/sync/event_processing_lttng_null.c b/lttv/lttv/sync/event_processing_lttng_null.c index 26971b26..1320753e 100644 --- a/lttv/lttv/sync/event_processing_lttng_null.c +++ b/lttv/lttv/sync/event_processing_lttng_null.c @@ -50,9 +50,6 @@ static ProcessingModule processingModuleLTTVNull = { .initProcessing= &initProcessingLTTVNull, .destroyProcessing= &destroyProcessingLTTVNull, .finalizeProcessing= &finalizeProcessingLTTVNull, - .printProcessingStats= NULL, - .writeProcessingGraphsPlots= NULL, - .writeProcessingGraphsOptions= NULL, }; diff --git a/lttv/lttv/sync/event_processing_lttng_standard.c b/lttv/lttv/sync/event_processing_lttng_standard.c index 0f1bda73..cc9ada28 100644 --- a/lttv/lttv/sync/event_processing_lttng_standard.c +++ b/lttv/lttv/sync/event_processing_lttng_standard.c @@ -47,7 +47,9 @@ static void destroyProcessingLTTVStandard(SyncState* const syncState); static void finalizeProcessingLTTVStandard(SyncState* const syncState); static void printProcessingStatsLTTVStandard(SyncState* const syncState); -static void writeProcessingGraphsOptionsLTTVStandard(SyncState* const +static void writeProcessingTraceTraceOptionsLTTVStandard(SyncState* const + syncState, const unsigned int i, const unsigned int j); +static void writeProcessingTraceTimeOptionsLTTVStandard(SyncState* const syncState, const unsigned int i, const unsigned int j); // Functions specific to this module @@ -62,12 +64,13 @@ static ProcessingModule processingModuleLTTVStandard = { .destroyProcessing= &destroyProcessingLTTVStandard, .finalizeProcessing= &finalizeProcessingLTTVStandard, .printProcessingStats= &printProcessingStatsLTTVStandard, - .writeProcessingGraphsPlots= NULL, - .writeProcessingGraphsOptions= &writeProcessingGraphsOptionsLTTVStandard, + .graphFunctions= { + .writeTraceTraceOptions= &writeProcessingTraceTraceOptionsLTTVStandard, + .writeTraceTimeOptions= &writeProcessingTraceTimeOptionsLTTVStandard, + }, }; - /* * Processing Module registering function */ @@ -679,7 +682,7 @@ static gboolean processEventLTTVStandard(void* hookData, void* callData) * i: first trace number * j: second trace number, garanteed to be larger than i */ -static void writeProcessingGraphsOptionsLTTVStandard(SyncState* const +static void writeProcessingTraceTraceOptionsLTTVStandard(SyncState* const syncState, const unsigned int i, const unsigned int j) { ProcessingDataLTTVStandard* processingData; @@ -704,3 +707,34 @@ static void writeProcessingGraphsOptionsLTTVStandard(SyncState* const "set y2tics\n", i, (double) traceI->startFreq / traceI->freqScale, j, (double) traceJ->startFreq / traceJ->freqScale); } + + +/* + * Write the processing-specific options in the gnuplot script. + * + * Args: + * syncState: container for synchronization data + * i: first trace number + * j: second trace number, garanteed to be larger than i + */ +static void writeProcessingTraceTimeOptionsLTTVStandard(SyncState* const + syncState, const unsigned int i, const unsigned int j) +{ + ProcessingDataLTTVStandard* processingData; + ProcessingGraphsLTTVStandard* traceI, * traceJ; + + processingData= (ProcessingDataLTTVStandard*) syncState->processingData; + + traceI= &processingData->graphs[i]; + traceJ= &processingData->graphs[j]; + + fprintf(syncState->graphsStream, + "set key inside right bottom\n" + "set xlabel \"Clock %1$u\"\n" + "set xtics nomirror\n" + "set ylabel \"time (s)\"\n" + "set ytics nomirror\n" + "set x2label \"Clock %1$d (s)\"\n" + "set x2range [GPVAL_X_MIN / %2$.1f : GPVAL_X_MAX / %2$.1f]\n" + "set x2tics\n", i, (double) traceI->startFreq / traceI->freqScale); +} diff --git a/lttv/lttv/sync/graph_functions.c b/lttv/lttv/sync/graph_functions.c new file mode 100644 index 00000000..9b61e120 --- /dev/null +++ b/lttv/lttv/sync/graph_functions.c @@ -0,0 +1,128 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2009 Benjamin Poirier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "sync_chain.h" +#include "graph_functions.h" + + +void writeGraphsScript(SyncState* const syncState) +{ + unsigned int i, j, k, l; + const struct { + size_t plotsOffset, + optionsOffset; + char* name; + } funcTypes[]= { + {offsetof(GraphFunctions, writeTraceTracePlots), + offsetof(GraphFunctions, writeTraceTraceOptions), "TraceTrace"}, + {offsetof(GraphFunctions, writeTraceTimePlots), + offsetof(GraphFunctions, writeTraceTimeOptions), "TraceTime"}, + }; + + for (l= 0; l < sizeof(funcTypes) / sizeof(*funcTypes); l++) + { + // 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 pos1, pos2, trunc; + const GraphFunctions* moduleGraphFunctions[]= { + &syncState->processingModule->graphFunctions, + &syncState->matchingModule->graphFunctions, + &syncState->analysisModule->graphFunctions, + }; + + fprintf(syncState->graphsStream, + "reset\n" + "set output \"%03d-%03d-%s.eps\"\n" + "plot \\\n", i, j, funcTypes[l].name); + + pos1= ftell(syncState->graphsStream); + + for (k= 0; k < sizeof(moduleGraphFunctions) / + sizeof(*moduleGraphFunctions); k++) + { + GraphFunction** writePlots= (void*) + moduleGraphFunctions[k] + funcTypes[l].plotsOffset; + + if (*writePlots) + { + (*writePlots)(syncState, i, j); + } + } + + 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(syncState->graphsStream, 0, SEEK_END) == -1) + { + g_error(strerror(errno)); + } + + fprintf(syncState->graphsStream, + "\nset output \"%03d-%03d-%s.eps\"\n" + "set title \"\"\n", i, j, funcTypes[l].name); + + for (k= 0; k < sizeof(moduleGraphFunctions) / + sizeof(*moduleGraphFunctions); k++) + { + GraphFunction** writeOptions= (void*) + moduleGraphFunctions[k] + funcTypes[l].optionsOffset; + + if (*writeOptions) + { + (*writeOptions)(syncState, i, j); + } + } + + if (pos1 != pos2) + { + fprintf(syncState->graphsStream, "replot\n\n"); + } + else + { + fprintf(syncState->graphsStream, "\n"); + } + } + } + } +} diff --git a/lttv/lttv/sync/graph_functions.h b/lttv/lttv/sync/graph_functions.h new file mode 100644 index 00000000..85e53a7a --- /dev/null +++ b/lttv/lttv/sync/graph_functions.h @@ -0,0 +1,42 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2009 Benjamin Poirier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef GRAPH_FUNCTIONS_H +#define GRAPH_FUNCTIONS_H + +struct _SyncState; + +typedef void (GraphFunction)(struct _SyncState* const syncState, const + unsigned int i, const unsigned int j); + +typedef struct +{ + /* This is for graphs where the data on both axis is in the range of + * timestamps */ + GraphFunction* writeTraceTracePlots; + GraphFunction* writeTraceTraceOptions; + /* This is for graphs where the data on the abscissa is in the range of + * timestamps and the ordinates is in the range of timestamp deltas */ + GraphFunction* writeTraceTimePlots; + GraphFunction* writeTraceTimeOptions; +} GraphFunctions; + + +void writeGraphsScript(struct _SyncState* const syncState); + +#endif diff --git a/lttv/lttv/sync/sync_chain_lttv.c b/lttv/lttv/sync/sync_chain_lttv.c index 4a701548..ae41ff67 100644 --- a/lttv/lttv/sync/sync_chain_lttv.c +++ b/lttv/lttv/sync/sync_chain_lttv.c @@ -169,7 +169,7 @@ void syncTraceset(LttvTracesetContext* const traceSetContext) struct timeval startTime, endTime; struct rusage startUsage, endUsage; GList* result; - unsigned int i, j; + unsigned int i; int retval; if (!optionSync.present) @@ -220,7 +220,7 @@ void syncTraceset(LttvTracesetContext* const traceSetContext) fprintf(syncState->graphsStream, "#!/usr/bin/gnuplot\n\n" - "set terminal postscript eps color size 8in,6in\n"); + "set terminal postscript eps color size 8in,6in\n\n"); retval= chdir(cwd); if (retval == -1) @@ -285,83 +285,7 @@ void syncTraceset(LttvTracesetContext* const traceSetContext) // Write graphs file if (optionSyncGraphs.present) { - // 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 pos1, pos2, trunc; - - fprintf(syncState->graphsStream, - "\nreset\n" - "set output \"%03d-%03d.eps\"\n" - "plot \\\n", 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); - } - - 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(syncState->graphsStream, 0, SEEK_END) == -1) - { - g_error(strerror(errno)); - } - - fprintf(syncState->graphsStream, - "\nset output \"%03d-%03d.eps\"\n" - "set title \"\"\n", 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); - } - - if (pos1 != pos2) - { - fprintf(syncState->graphsStream, "replot\n"); - } - } - } + writeGraphsScript(syncState); if (fclose(syncState->graphsStream) != 0) { diff --git a/lttv/modules/text/sync_chain_batch.c b/lttv/modules/text/sync_chain_batch.c index 8ac77fd9..2b2990ff 100644 --- a/lttv/modules/text/sync_chain_batch.c +++ b/lttv/modules/text/sync_chain_batch.c @@ -316,7 +316,7 @@ void setupSyncChain(LttvTracesetContext* const traceSetContext) fprintf(syncState->graphsStream, "#!/usr/bin/gnuplot\n\n" - "set terminal postscript eps color size 8in,6in\n"); + "set terminal postscript eps color size 8in,6in\n\n"); retval= chdir(cwd); if (retval == -1) @@ -374,84 +374,7 @@ void teardownSyncChain(LttvTracesetContext* const traceSetContext) // Write graphs file if (optionEvalGraphs) { - // 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 pos1, pos2, trunc; - - fprintf(syncState->graphsStream, - "\nreset\n" - "set output \"%03d-%03d.eps\"\n" - "plot \\\n", i, j); - pos1= ftell(syncState->graphsStream); - - 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); - } - - 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(syncState->graphsStream, 0, SEEK_END) == -1) - { - g_error(strerror(errno)); - } - - fprintf(syncState->graphsStream, - "\nset output \"%1$03d-%2$03d.eps\"\n" - "set title \"\"\n", 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); - } - - if (pos1 != pos2) - { - fprintf(syncState->graphsStream, "replot\n"); - } - } - } + writeGraphsScript(syncState); if (fclose(syncState->graphsStream) != 0) {