X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Fsync%2Fsync_chain_lttv.c;h=95bef4418e4e8f1746e0f7dcb8c983a3217622ec;hb=b2da0724a95cdb911c07640268b65bd9c5b92010;hp=c0693b7e50d447c2b5d98f61b2e00a25801906a5;hpb=277e5b535febfb81a5e9485b0d008e148b6979ac;p=lttv.git diff --git a/lttv/lttv/sync/sync_chain_lttv.c b/lttv/lttv/sync/sync_chain_lttv.c index c0693b7e..95bef441 100644 --- a/lttv/lttv/sync/sync_chain_lttv.c +++ b/lttv/lttv/sync/sync_chain_lttv.c @@ -15,12 +15,15 @@ * along with this program. If not, see . */ +#define _ISOC99_SOURCE + #ifdef HAVE_CONFIG_H #include #endif #include #include +#include #include #include #include @@ -41,6 +44,7 @@ #include "event_analysis_chull.h" #include "event_analysis_linreg.h" #include "event_analysis_eval.h" +#include "factor_reduction_accuracy.h" #include "sync_chain.h" #include "sync_chain_lttv.h" @@ -72,6 +76,12 @@ static ModuleOption optionSyncAnalysis= { .hasArg= REQUIRED_ARG, .optionHelp= "specify the algorithm to use for event analysis", }; +static GString* reductionModulesNames; +static ModuleOption optionSyncReduction= { + .longName= "sync-reduction", + .hasArg= REQUIRED_ARG, + .optionHelp= "specify the algorithm to use for factor reduction", +}; static ModuleOption optionSyncGraphs= { .longName= "sync-graphs", .hasArg= NO_ARG, @@ -93,6 +103,20 @@ static ModuleOption optionSyncGraphsDir= { static void init() { int retval; + unsigned int i; + const struct + { + GQueue* modules; + ModuleOption* option; + size_t nameOffset; + GString** names; + void (*gfAppendName)(gpointer data, gpointer user_data); + } loopValues[]= { + {&analysisModules, &optionSyncAnalysis, offsetof(AnalysisModule, + name), &analysisModulesNames, &gfAppendAnalysisName}, + {&reductionModules, &optionSyncReduction, offsetof(ReductionModule, + name), &reductionModulesNames, &gfAppendReductionName}, + }; g_debug("Sync init"); @@ -114,15 +138,23 @@ static void init() registerAnalysisLinReg(); registerAnalysisEval(); - g_assert(g_queue_get_length(&analysisModules) > 0); - 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); - optionSyncAnalysis.argHelp= analysisModulesNames->str; + registerReductionAccuracy(); + + // Build module names lists for option and help string + for (i= 0; i < ARRAY_SIZE(loopValues); i++) + { + g_assert(g_queue_get_length(loopValues[i].modules) > 0); + loopValues[i].option->arg= (char*)(*(void**) + g_queue_peek_head(loopValues[i].modules) + + loopValues[i].nameOffset); + *loopValues[i].names= g_string_new(""); + g_queue_foreach(loopValues[i].modules, loopValues[i].gfAppendName, + *loopValues[i].names); + // remove the last ", " + g_string_truncate(*loopValues[i].names, (*loopValues[i].names)->len - + 2); + loopValues[i].option->argHelp= (*loopValues[i].names)->str; + } retval= snprintf(graphsDir, sizeof(graphsDir), "graphs-%d", getpid()); if (retval > sizeof(graphsDir) - 1) @@ -134,6 +166,7 @@ static void init() g_queue_push_head(&moduleOptions, &optionSyncGraphsDir); g_queue_push_head(&moduleOptions, &optionSyncGraphs); + g_queue_push_head(&moduleOptions, &optionSyncReduction); g_queue_push_head(&moduleOptions, &optionSyncAnalysis); g_queue_push_head(&moduleOptions, &optionSyncNull); g_queue_push_head(&moduleOptions, &optionSyncStats); @@ -152,10 +185,12 @@ static void destroy() g_queue_foreach(&moduleOptions, &gfRemoveModuleOption, NULL); g_string_free(analysisModulesNames, TRUE); + g_string_free(reductionModulesNames, TRUE); g_queue_clear(&processingModules); g_queue_clear(&matchingModules); g_queue_clear(&analysisModules); + g_queue_clear(&reductionModules); g_queue_clear(&moduleOptions); } @@ -178,6 +213,10 @@ bool syncTraceset(LttvTracesetContext* const traceSetContext) struct rusage startUsage, endUsage; GList* result; unsigned int i; + AllFactors* allFactors; + GArray* factors; + double minOffset, minDrift; + unsigned int refFreqTrace; int retval; if (!optionSync.present) @@ -249,11 +288,24 @@ bool syncTraceset(LttvTracesetContext* const traceSetContext) g_error("Analysis module '%s' not found", optionSyncAnalysis.arg); } + syncState->reductionData= NULL; + result= g_queue_find_custom(&reductionModules, optionSyncReduction.arg, + &gcfCompareReduction); + if (result != NULL) + { + syncState->reductionModule= (ReductionModule*) result->data; + } + else + { + g_error("Reduction module '%s' not found", optionSyncReduction.arg); + } + syncState->processingModule->initProcessing(syncState, traceSetContext); if (!optionSyncNull.present) { syncState->matchingModule->initMatching(syncState); syncState->analysisModule->initAnalysis(syncState); + syncState->reductionModule->initReduction(syncState); } // Process traceset @@ -262,7 +314,72 @@ bool syncTraceset(LttvTracesetContext* const traceSetContext) G_MAXULONG, NULL); lttv_process_traceset_seek_time(traceSetContext, ltt_time_zero); - syncState->processingModule->finalizeProcessing(syncState); + // Obtain, reduce, adjust and set correction factors + allFactors= syncState->processingModule->finalizeProcessing(syncState); + factors= syncState->reductionModule->finalizeReduction(syncState, + allFactors); + freeAllFactors(allFactors, syncState->traceNb); + + /* The offsets are adjusted so the lowest one is 0. This is done because + * of a Lttv specific limitation: events cannot have negative times. By + * having non-negative offsets, events cannot be moved backwards to + * negative times. + */ + minOffset= 0; + for (i= 0; i < syncState->traceNb; i++) + { + minOffset= MIN(g_array_index(factors, Factors, i).offset, minOffset); + } + + for (i= 0; i < syncState->traceNb; i++) + { + g_array_index(factors, Factors, i).offset-= minOffset; + } + + /* Because the timestamps are corrected at the TSC level (not at the + * LttTime level) all trace frequencies must be made equal. We use the + * frequency of the system with the lowest drift + */ + minDrift= INFINITY; + refFreqTrace= 0; + for (i= 0; i < syncState->traceNb; i++) + { + if (g_array_index(factors, Factors, i).drift < minDrift) + { + minDrift= g_array_index(factors, Factors, i).drift; + refFreqTrace= i; + } + } + g_assert(syncState->traceNb == 0 || minDrift != INFINITY); + + // Write the factors to the LttTrace structures + for (i= 0; i < syncState->traceNb; i++) + { + LttTrace* t; + Factors* traceFactors; + + t= traceSetContext->traces[i]->t; + traceFactors= &g_array_index(factors, Factors, i); + + t->drift= traceFactors->drift; + t->offset= traceFactors->offset; + t->start_freq= traceSetContext->traces[refFreqTrace]->t->start_freq; + t->freq_scale= traceSetContext->traces[refFreqTrace]->t->freq_scale; + t->start_time_from_tsc = + ltt_time_from_uint64(tsc_to_uint64(t->freq_scale, t->start_freq, + t->drift * t->start_tsc + t->offset)); + } + + g_array_free(factors, TRUE); + + lttv_traceset_context_compute_time_span(traceSetContext, + &traceSetContext->time_span); + + g_debug("traceset start %ld.%09ld end %ld.%09ld", + traceSetContext->time_span.start_time.tv_sec, + traceSetContext->time_span.start_time.tv_nsec, + traceSetContext->time_span.end_time.tv_sec, + traceSetContext->time_span.end_time.tv_nsec); // Write graphs file if (!optionSyncNull.present && optionSyncGraphs.present) @@ -303,6 +420,10 @@ bool syncTraceset(LttvTracesetContext* const traceSetContext) { syncState->analysisModule->destroyAnalysis(syncState); } + if (syncState->reductionModule != NULL) + { + syncState->reductionModule->destroyReduction(syncState); + } free(syncState);