X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=lttv%2Flttv%2Fsync%2Fsync_chain_unittest.c;h=276c71ce2d4b80396016a3f402cfcd29f44e76a5;hb=1111bb0f69e3c01c9264b19cbc7d2a8a02eeb569;hp=3a6de5710e7a7e71ed3eb03d6a2ee2c0d8b23e1f;hpb=b670bb7cf8ff6e781462434a2273e47e055e54db;p=lttv.git diff --git a/lttv/lttv/sync/sync_chain_unittest.c b/lttv/lttv/sync/sync_chain_unittest.c index 3a6de571..276c71ce 100644 --- a/lttv/lttv/sync/sync_chain_unittest.c +++ b/lttv/lttv/sync/sync_chain_unittest.c @@ -1,19 +1,18 @@ /* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2009 Benjamin Poirier + * Copyright (C) 2009, 2010 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 free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or (at + * your option) any later version. * - * 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. + * 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 Lesser 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. + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . */ #define _GNU_SOURCE @@ -35,6 +34,14 @@ #include #include +#include "event_processing_text.h" +#include "event_matching_tcp.h" +#include "event_matching_broadcast.h" +#include "event_matching_distributor.h" +#include "event_analysis_chull.h" +#include "event_analysis_linreg.h" +#include "event_analysis_eval.h" +#include "factor_reduction_accuracy.h" #include "sync_chain.h" @@ -42,7 +49,8 @@ struct OptionsInfo { GArray* longOptions; GString* optionString; - GQueue* index; + GQueue* longIndex; + GHashTable* shortIndex; }; @@ -52,6 +60,8 @@ static void gfPrintModuleOption(gpointer data, gpointer user_data); static void nullLog(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); static void gfAddModuleOption(gpointer data, gpointer user_data); +static guint ghfCharHash(gconstpointer key); +static gboolean gefCharEqual(gconstpointer a, gconstpointer b); static ModuleOption optionSyncStats= { @@ -73,6 +83,12 @@ static ModuleOption optionSyncAnalysis= { .hasArg= REQUIRED_ARG, .optionHelp= "Specify which algorithm to use for event analysis", }; +static ModuleOption optionSyncReduction= { + .shortName= 'r', + .longName= "sync-reduction", + .hasArg= REQUIRED_ARG, + .optionHelp= "Specify which algorithm to use for factor reduction", +}; /* @@ -91,10 +107,33 @@ int main(const int argc, char* const argv[]) struct timeval startTime, endTime; struct rusage startUsage, endUsage; GList* result; + GArray* factors; int retval; bool stats; const char* testCaseName; GString* analysisModulesNames; + GString* reductionModulesNames; + unsigned int id; + AllFactors* allFactors; + + /* + * Initialize event modules + * Call the "constructor" or initialization function of each event module + * so it can register itself. This must be done before elements in + * processingModules, matchingModules, analysisModules or moduleOptions + * are accessed. + */ + registerProcessingText(); + + registerMatchingTCP(); + registerMatchingBroadcast(); + registerMatchingDistributor(); + + registerAnalysisCHull(); + registerAnalysisLinReg(); + registerAnalysisEval(); + + registerReductionAccuracy(); // Initialize data structures syncState= malloc(sizeof(SyncState)); @@ -110,6 +149,16 @@ int main(const int argc, char* const argv[]) g_string_truncate(analysisModulesNames, analysisModulesNames->len - 2); optionSyncAnalysis.argHelp= analysisModulesNames->str; + g_assert(g_queue_get_length(&reductionModules) > 0); + optionSyncReduction.arg= ((ReductionModule*) + g_queue_peek_head(&reductionModules))->name; + reductionModulesNames= g_string_new("Available modules: "); + g_queue_foreach(&reductionModules, &gfAppendReductionName, + reductionModulesNames); + // remove the last ", " + g_string_truncate(reductionModulesNames, reductionModulesNames->len - 2); + optionSyncReduction.argHelp= reductionModulesNames->str; + retval= snprintf(graphsDir, sizeof(graphsDir), "graphs-%d", getpid()); if (retval > sizeof(graphsDir) - 1) { @@ -117,6 +166,7 @@ int main(const int argc, char* const argv[]) } optionSyncGraphs.arg= graphsDir; + g_queue_push_head(&moduleOptions, &optionSyncReduction); g_queue_push_head(&moduleOptions, &optionSyncAnalysis); g_queue_push_head(&moduleOptions, &optionSyncGraphs); g_queue_push_head(&moduleOptions, &optionSyncStats); @@ -124,6 +174,7 @@ int main(const int argc, char* const argv[]) testCaseName= processOptions(argc, argv); g_string_free(analysisModulesNames, TRUE); + g_string_free(reductionModulesNames, TRUE); if (optionSyncStats.present) { @@ -134,7 +185,7 @@ int main(const int argc, char* const argv[]) else { syncState->stats= false; - g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, nullLog, NULL); + id= g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, nullLog, NULL); } if (optionSyncGraphs.present) @@ -174,13 +225,29 @@ int main(const int argc, char* const argv[]) 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); + } + // Initialize modules syncState->processingModule->initProcessing(syncState, testCaseName); syncState->matchingModule->initMatching(syncState); syncState->analysisModule->initAnalysis(syncState); + syncState->reductionModule->initReduction(syncState); // Process traceset - syncState->processingModule->finalizeProcessing(syncState); + allFactors= syncState->processingModule->finalizeProcessing(syncState); + factors= syncState->reductionModule->finalizeReduction(syncState, + allFactors); + freeAllFactors(allFactors, syncState->traceNb); // Write graphs file if (syncState->graphsStream) @@ -189,20 +256,31 @@ int main(const int argc, char* const argv[]) if (fclose(syncState->graphsStream) != 0) { - g_error(strerror(errno)); + g_error("%s", strerror(errno)); } } // Print statistics - if (syncState->stats) + if (optionSyncStats.present) { + unsigned int i; + printStats(syncState); + + printf("Resulting synchronization factors:\n"); + for (i= 0; i < factors->len; i++) + { + Factors* traceFactors= &g_array_index(factors, Factors, i); + printf("\ttrace %u drift= %g offset= %g\n", i, + traceFactors->drift, traceFactors->offset); + } } // Destroy modules and clean up syncState->processingModule->destroyProcessing(syncState); syncState->matchingModule->destroyMatching(syncState); syncState->analysisModule->destroyAnalysis(syncState); + syncState->reductionModule->destroyReduction(syncState); stats= syncState->stats; free(syncState); @@ -224,12 +302,17 @@ int main(const int argc, char* const argv[]) endUsage.ru_stime.tv_usec); } + if (!optionSyncStats.present) + { + g_log_remove_handler(NULL, id); + } + return EXIT_SUCCESS; } /* - * Read program arguments dans update ModuleOptions structures + * Read program arguments and update ModuleOptions structures * * Args: * argc, argv: standard argument arrays @@ -244,34 +327,34 @@ const char* processOptions(const int argc, char* const argv[]) extern int optind, opterr, optopt; GArray* longOptions; GString* optionString; - GQueue* index; + GQueue* longIndex; + int longOption; + GHashTable* shortIndex; longOptions= g_array_sized_new(TRUE, FALSE, sizeof(struct option), g_queue_get_length(&moduleOptions)); optionString= g_string_new(""); - index= g_queue_new(); + longIndex= g_queue_new(); + shortIndex= g_hash_table_new(&ghfCharHash, &gefCharEqual); g_queue_foreach(&moduleOptions, &gfAddModuleOption, &(struct OptionsInfo) - {longOptions, optionString, index}); + {longOptions, optionString, longIndex, shortIndex}); do { int optionIndex= 0; + ModuleOption* moduleOption; + longOption= -1; c= getopt_long(argc, argv, optionString->str, (struct option*) longOptions->data, &optionIndex); - if (c >= 0 && c < g_queue_get_length(index)) + if (longOption >= 0 && longOption < g_queue_get_length(longIndex)) + { + moduleOption= g_queue_peek_nth(longIndex, longOption); + } + else if ((moduleOption= g_hash_table_lookup(shortIndex, &c)) != NULL) { - ModuleOption* moduleOption= g_queue_peek_nth(index, c); - - moduleOption->present= true; - - if (moduleOption->hasArg == REQUIRED_ARG || moduleOption->hasArg - == OPTIONAL_ARG) - { - moduleOption->arg= optarg; - } } else if (c == -1) { @@ -286,10 +369,23 @@ const char* processOptions(const int argc, char* const argv[]) { g_error("Option parse error"); } + + moduleOption->present= true; + + if (moduleOption->hasArg == REQUIRED_ARG) + { + moduleOption->arg= optarg; + } + if (moduleOption->hasArg == OPTIONAL_ARG && optarg) + { + moduleOption->arg= optarg; + } } while (c != -1); g_array_free(longOptions, TRUE); g_string_free(optionString, TRUE); + g_queue_free(longIndex); + g_hash_table_destroy(shortIndex); if (argc <= optind) { @@ -403,9 +499,50 @@ static void gfAddModuleOption(gpointer data, gpointer user_data) newOption.name= option->longName; newOption.has_arg= conversion[option->hasArg]; newOption.flag= NULL; - newOption.val= g_queue_get_length(optionsInfo->index); + newOption.val= g_queue_get_length(optionsInfo->longIndex); g_array_append_val(optionsInfo->longOptions, newOption); - g_string_append(optionsInfo->optionString, colons[option->hasArg]); - g_queue_push_tail(optionsInfo->index, option); + if (option->shortName) + { + g_string_append_c(optionsInfo->optionString, option->shortName); + g_string_append(optionsInfo->optionString, colons[option->hasArg]); + + g_hash_table_insert(optionsInfo->shortIndex, &option->shortName, + option); + } + g_queue_push_tail(optionsInfo->longIndex, option); +} + + +/* + * A GHashFunc for g_hash_table_new() + * + * Args: + * key char*, just one character + */ +static guint ghfCharHash(gconstpointer key) +{ + return *(char*) key; +} + + +/* + * A GEqualFunc for g_hash_table_new() + * + * Args: + * a, b char*, just one character each + * + * Returns: + * TRUE if both values are equal + */ +static gboolean gefCharEqual(gconstpointer a, gconstpointer b) +{ + if (*(char*) a == *(char*) b) + { + return TRUE; + } + else + { + return FALSE; + } }