From ffa21cfde7a086c1558b961ffa0fcbe75513a7f6 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Fri, 13 Nov 2009 15:30:07 -0500 Subject: [PATCH] Generate graphs of broadcasts Signed-off-by: Benjamin Poirier --- lttv/lttv/sync/data_structures.h | 2 + lttv/lttv/sync/event_analysis_eval.c | 13 +- lttv/lttv/sync/event_matching_broadcast.c | 203 +++++++++++++++++++++- lttv/lttv/sync/event_matching_broadcast.h | 25 +++ 4 files changed, 232 insertions(+), 11 deletions(-) diff --git a/lttv/lttv/sync/data_structures.h b/lttv/lttv/sync/data_structures.h index 697f29a6..5f5e4be3 100644 --- a/lttv/lttv/sync/data_structures.h +++ b/lttv/lttv/sync/data_structures.h @@ -113,11 +113,13 @@ typedef struct _Message typedef struct { Message* message; + // Event* acks[] GQueue* acks; } Exchange; typedef struct { + // Event* events[] GQueue* events; } Broadcast; diff --git a/lttv/lttv/sync/event_analysis_eval.c b/lttv/lttv/sync/event_analysis_eval.c index b8f3b858..dd831087 100644 --- a/lttv/lttv/sync/event_analysis_eval.c +++ b/lttv/lttv/sync/event_analysis_eval.c @@ -702,11 +702,14 @@ static void printAnalysisStatsEval(SyncState* const syncState) analysisData= (AnalysisDataEval*) syncState->analysisData; printf("Synchronization evaluation analysis stats:\n"); - printf("\tsum of broadcast differential delays: %g\n", - analysisData->stats->broadcastDiffSum); - printf("\taverage broadcast differential delays: %g\n", - analysisData->stats->broadcastDiffSum / - analysisData->stats->broadcastNb); + if (analysisData->stats->broadcastNb) + { + printf("\tsum of broadcast differential delays: %g\n", + analysisData->stats->broadcastDiffSum); + printf("\taverage broadcast differential delays: %g\n", + analysisData->stats->broadcastDiffSum / + analysisData->stats->broadcastNb); + } printf("\tIndividual evaluation:\n" "\t\tTrace pair Inversions Too fast No RTT info Total\n"); diff --git a/lttv/lttv/sync/event_matching_broadcast.c b/lttv/lttv/sync/event_matching_broadcast.c index 297de2cd..98bab58a 100644 --- a/lttv/lttv/sync/event_matching_broadcast.c +++ b/lttv/lttv/sync/event_matching_broadcast.c @@ -43,12 +43,21 @@ static void destroyMatchingBroadcast(SyncState* const syncState); static void matchEventBroadcast(SyncState* const syncState, Event* const event); static GArray* finalizeMatchingBroadcast(SyncState* const syncState); static void printMatchingStatsBroadcast(SyncState* const syncState); +static void writeMatchingGraphsPlotsBroadcast(SyncState* const syncState, const + unsigned int i, const unsigned int j); // Functions specific to this module static void registerMatchingBroadcast() __attribute__((constructor (101))); static void partialDestroyMatchingBroadcast(SyncState* const syncState); +static void openGraphDataFiles(SyncState* const syncState); +static void writeAccuracyPoints(MatchingGraphsBroadcast* graphs, const + Broadcast* const broadcast); +void gfAddToArray(gpointer data, gpointer user_data); +static void closeGraphDataFiles(SyncState* const syncState); + + static MatchingModule matchingModuleBroadcast = { .name= "broadcast", .canMatch[TCP]= false, @@ -58,7 +67,7 @@ static MatchingModule matchingModuleBroadcast = { .matchEvent= &matchEventBroadcast, .finalizeMatching= &finalizeMatchingBroadcast, .printMatchingStats= &printMatchingStatsBroadcast, - .writeMatchingGraphsPlots= NULL, + .writeMatchingGraphsPlots= &writeMatchingGraphsPlotsBroadcast, .writeMatchingGraphsOptions= NULL, }; @@ -104,6 +113,16 @@ static void initMatchingBroadcast(SyncState* const syncState) { matchingData->stats= NULL; } + + if (syncState->graphsStream) + { + matchingData->graphs= malloc(sizeof(MatchingGraphsBroadcast)); + openGraphDataFiles(syncState); + } + else + { + matchingData->graphs= NULL; + } } @@ -119,9 +138,8 @@ static void initMatchingBroadcast(SyncState* const syncState) */ static void destroyMatchingBroadcast(SyncState* const syncState) { - MatchingDataBroadcast* matchingData; - - matchingData= (MatchingDataBroadcast*) syncState->matchingData; + MatchingDataBroadcast* matchingData= syncState->matchingData; + unsigned int i; if (matchingData == NULL) { @@ -135,6 +153,16 @@ static void destroyMatchingBroadcast(SyncState* const syncState) free(matchingData->stats); } + if (syncState->graphsStream) + { + for (i= 0; i < syncState->traceNb; i++) + { + free(matchingData->graphs->pointsNb[i]); + } + free(matchingData->graphs->pointsNb); + free(matchingData->graphs); + } + free(syncState->matchingData); syncState->matchingData= NULL; } @@ -164,14 +192,18 @@ static void partialDestroyMatchingBroadcast(SyncState* const syncState) g_hash_table_destroy(matchingData->pendingBroadcasts); matchingData->pendingBroadcasts= NULL; + + if (syncState->graphsStream && matchingData->graphs->accuracyPoints) + { + closeGraphDataFiles(syncState); + } } /* * Try to match one broadcast with previously received broadcasts (based on * the addresses and the fist bytes of data they contain). Deliver them to the - * analysis module once a traceNb events have been accumulated for a - * broadcast. + * analysis module once traceNb events have been accumulated for a broadcast. * * Args: * syncState container for synchronization data. @@ -224,6 +256,11 @@ static void matchEventBroadcast(SyncState* const syncState, Event* const event) g_hash_table_steal(matchingData->pendingBroadcasts, datagramKey); free(datagramKey); syncState->analysisModule->analyzeBroadcast(syncState, broadcast); + + if (syncState->graphsStream) + { + writeAccuracyPoints(matchingData->graphs, broadcast); + } destroyBroadcast(broadcast); } } @@ -319,3 +356,157 @@ static void printMatchingStatsBroadcast(SyncState* const syncState) matchingData->stats->totIncomplete); } } + + +/* + * Create and open files used to store accuracy points to genereate graphs. + * Allocate and populate array to store file pointers and counters. + * + * Args: + * syncState: container for synchronization data + */ +static void openGraphDataFiles(SyncState* const syncState) +{ + unsigned int i, j; + int retval; + char* cwd; + char name[36]; + MatchingGraphsBroadcast* graphs= ((MatchingDataBroadcast*) + syncState->matchingData)->graphs; + + cwd= changeToGraphDir(syncState->graphsDir); + + graphs->accuracyPoints= malloc(syncState->traceNb * sizeof(FILE**)); + graphs->pointsNb= malloc(syncState->traceNb * sizeof(unsigned int*)); + for (i= 0; i < syncState->traceNb; i++) + { + graphs->accuracyPoints[i]= malloc(i * sizeof(FILE*)); + graphs->pointsNb[i]= calloc(i, sizeof(unsigned int)); + for (j= 0; j < i; j++) + { + retval= snprintf(name, sizeof(name), + "matching_broadcast-%03u_and_%03u.data", j, i); + g_assert_cmpint(retval, <=, sizeof(name) - 1); + if ((graphs->accuracyPoints[i][j]= fopen(name, "w")) == NULL) + { + g_error(strerror(errno)); + } + } + } + + retval= chdir(cwd); + if (retval == -1) + { + g_error(strerror(errno)); + } + free(cwd); +} + + +/* + * Calculate and write points used to generate graphs + * + * Args: + * graphs: structure containing array of file pointers and counters + * broadcast: broadcast for which to write the points + */ +static void writeAccuracyPoints(MatchingGraphsBroadcast* graphs, const + Broadcast* const broadcast) +{ + unsigned int i, j; + GArray* events; + unsigned int eventNb= broadcast->events->length; + + events= g_array_sized_new(FALSE, FALSE, sizeof(Event*), eventNb); + g_queue_foreach(broadcast->events, &gfAddToArray, events); + + for (i= 0; i < eventNb; i++) + { + for (j= 0; j < eventNb; j++) + { + Event* eventI= g_array_index(events, Event*, i), * eventJ= + g_array_index(events, Event*, j); + + if (eventI->traceNum < eventJ->traceNum) + { + fprintf(graphs->accuracyPoints[eventJ->traceNum][eventI->traceNum], + "%20llu %20lld\n", eventI->cpuTime, (int64_t) eventJ->cpuTime - + eventI->cpuTime); + graphs->pointsNb[eventJ->traceNum][eventI->traceNum]++; + } + } + } +} + + +/* + * A GFunc for g_queue_foreach() + * + * Args: + * data Event*, event to add + * user_data GArray*, array to add to + */ +void gfAddToArray(gpointer data, gpointer user_data) +{ + g_array_append_val((GArray*) user_data, data); +} + + +/* + * Close files used to store accuracy points to genereate graphs. Deallocate + * array to store file pointers (but not array for counters). + * + * Args: + * syncState: container for synchronization data + */ +static void closeGraphDataFiles(SyncState* const syncState) +{ + unsigned int i, j; + MatchingGraphsBroadcast* graphs= ((MatchingDataBroadcast*) + syncState->matchingData)->graphs; + int retval; + + if (graphs->accuracyPoints == NULL) + { + return; + } + + for (i= 0; i < syncState->traceNb; i++) + { + for (j= 0; j < i; j++) + { + retval= fclose(graphs->accuracyPoints[i][j]); + if (retval != 0) + { + g_error(strerror(errno)); + } + } + free(graphs->accuracyPoints[i]); + } + free(graphs->accuracyPoints); + + graphs->accuracyPoints= NULL; +} + + +/* + * Write the matching-specific graph lines 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 writeMatchingGraphsPlotsBroadcast(SyncState* const syncState, const + unsigned int i, const unsigned int j) +{ + if (((MatchingDataBroadcast*) + syncState->matchingData)->graphs->pointsNb[j][i]) + { + fprintf(syncState->graphsStream, + "\t\"matching_broadcast-%03d_and_%03d.data\" " + "title \"Broadcast delays\" with points " + "linecolor rgb \"black\" pointtype 6 pointsize 2, \\\n", i, + j); + } +} diff --git a/lttv/lttv/sync/event_matching_broadcast.h b/lttv/lttv/sync/event_matching_broadcast.h index 3492f0a7..8006cdd1 100644 --- a/lttv/lttv/sync/event_matching_broadcast.h +++ b/lttv/lttv/sync/event_matching_broadcast.h @@ -32,12 +32,37 @@ typedef struct totTransmit; } MatchingStatsBroadcast; +typedef struct +{ + /* This array is used for graphs. It contains file pointers to files where + * broadcast differential delay points are output. + * + * accuracyPoints is divided into three parts depending on the position of an + * element accuracyPoints[i][j]: + * Lower triangular part of the matrix + * i > j + * This contains the difference t[i] - t[j] between the times when + * a broadcast was received in trace i and trace j. + * Diagonal part of the matrix + * i = j + * This area is not allocated. + * Upper triangular part of the matrix + * i < j + * This area is not allocated. + */ + FILE*** accuracyPoints; + + // pointsNb[traceNum][traceNum] has the same structure as accuracyPoints + unsigned int** pointsNb; +} MatchingGraphsBroadcast; + typedef struct { // Broadcast* pendingBroadcasts[dataStart] GHashTable* pendingBroadcasts; MatchingStatsBroadcast* stats; + MatchingGraphsBroadcast* graphs; } MatchingDataBroadcast; #endif -- 2.34.1