1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include <sys/resource.h>
27 #include <lttv/module.h>
28 #include <lttv/option.h>
30 #include "sync_chain.h"
34 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
39 static void destroy();
41 static void timeDiff(struct timeval
* const end
, const struct timeval
* const start
);
42 static gint
gcfCompareAnalysis(gconstpointer a
, gconstpointer b
);
43 static gint
gcfCompareProcessing(gconstpointer a
, gconstpointer b
);
44 static void gfAppendAnalysisName(gpointer data
, gpointer user_data
);
46 static gboolean optionSync
;
47 static gboolean optionSyncStats
;
48 static gboolean optionSyncNull
;
49 static char* optionSyncAnalysis
;
51 GQueue processingModules
= G_QUEUE_INIT
;
52 GQueue matchingModules
= G_QUEUE_INIT
;
53 GQueue analysisModules
= G_QUEUE_INIT
;
57 * Module init function
59 * This function is declared to be the module initialization function. Event
60 * modules are registered with a "constructor (102)" attribute except one in
61 * each class (processing, matching, analysis) which is chosen to be the
62 * default and which is registered with a "constructor (101)" attribute.
63 * Constructors with no priority are called after constructors with
64 * priorities. The result is that the list of event modules is known when this
65 * function is executed.
69 GString
* analysisModulesNames
;
71 g_debug("\t\t\tXXXX sync init\n");
74 lttv_option_add("sync", '\0', "synchronize the time between the traces" ,
75 "none", LTTV_OPT_NONE
, &optionSync
, NULL
, NULL
);
77 optionSyncStats
= FALSE
;
78 lttv_option_add("sync-stats", '\0', "print statistics about the time "
79 "synchronization", "none", LTTV_OPT_NONE
, &optionSyncStats
, NULL
,
82 optionSyncNull
= FALSE
;
83 lttv_option_add("sync-null", '\0', "read the events but do not perform "
84 "any processing", "none", LTTV_OPT_NONE
, &optionSyncNull
, NULL
, NULL
);
86 g_assert(g_queue_get_length(&analysisModules
) > 0);
87 optionSyncAnalysis
= ((AnalysisModule
*)
88 g_queue_peek_head(&analysisModules
))->name
;
89 analysisModulesNames
= g_string_new("");
90 g_queue_foreach(&analysisModules
, &gfAppendAnalysisName
,
91 analysisModulesNames
);
92 // remove the last ", "
93 g_string_truncate(analysisModulesNames
, analysisModulesNames
->len
- 2);
94 lttv_option_add("sync-analysis", '\0', "specify the algorithm to use for "
95 "event analysis" , analysisModulesNames
->str
, LTTV_OPT_STRING
,
96 &optionSyncAnalysis
, NULL
, NULL
);
97 g_string_free(analysisModulesNames
, TRUE
);
102 * Module unload function
104 static void destroy()
106 g_debug("\t\t\tXXXX sync destroy\n");
108 lttv_option_remove("sync");
109 lttv_option_remove("sync-stats");
110 lttv_option_remove("sync-null");
111 lttv_option_remove("sync-analysis");
116 * Calculate a traceset's drift and offset values based on network events
118 * The individual correction factors are written out to each trace.
121 * traceSetContext: traceset
123 void syncTraceset(LttvTracesetContext
* const traceSetContext
)
125 SyncState
* syncState
;
126 struct timeval startTime
, endTime
;
127 struct rusage startUsage
, endUsage
;
131 if (optionSync
== FALSE
)
133 g_debug("Not synchronizing traceset because option is disabled");
139 gettimeofday(&startTime
, 0);
140 getrusage(RUSAGE_SELF
, &startUsage
);
143 // Initialize data structures
144 syncState
= malloc(sizeof(SyncState
));
145 syncState
->traceNb
= lttv_traceset_number(traceSetContext
->ts
);
149 syncState
->stats
= true;
153 syncState
->stats
= false;
156 syncState
->processingData
= NULL
;
159 result
= g_queue_find_custom(&processingModules
, "LTTV-null",
160 &gcfCompareProcessing
);
164 result
= g_queue_find_custom(&processingModules
, "LTTV-standard",
165 &gcfCompareProcessing
);
167 g_assert(result
!= NULL
);
168 syncState
->processingModule
= (ProcessingModule
*) result
->data
;
169 syncState
->processingModule
->initProcessing(syncState
, traceSetContext
);
171 syncState
->matchingData
= NULL
;
172 syncState
->analysisData
= NULL
;
175 syncState
->matchingModule
= NULL
;
176 syncState
->analysisModule
= NULL
;
180 g_assert(g_queue_get_length(&matchingModules
) == 1);
181 syncState
->matchingModule
= (MatchingModule
*)
182 g_queue_peek_head(&matchingModules
);
183 syncState
->matchingModule
->initMatching(syncState
);
185 result
= g_queue_find_custom(&analysisModules
, optionSyncAnalysis
,
186 &gcfCompareAnalysis
);
189 syncState
->analysisModule
= (AnalysisModule
*) result
->data
;
190 syncState
->analysisModule
->initAnalysis(syncState
);
194 g_error("Analysis module '%s' not found", optionSyncAnalysis
);
199 lttv_process_traceset_seek_time(traceSetContext
, ltt_time_zero
);
200 lttv_process_traceset_middle(traceSetContext
, ltt_time_infinite
,
202 lttv_process_traceset_seek_time(traceSetContext
, ltt_time_zero
);
204 syncState
->processingModule
->finalizeProcessing(syncState
);
206 if (syncState
->processingModule
->printProcessingStats
!= NULL
)
208 syncState
->processingModule
->printProcessingStats(syncState
);
211 syncState
->processingModule
->destroyProcessing(syncState
);
212 if (syncState
->matchingModule
!= NULL
)
214 syncState
->matchingModule
->destroyMatching(syncState
);
216 if (syncState
->analysisModule
!= NULL
)
218 syncState
->analysisModule
->destroyAnalysis(syncState
);
225 gettimeofday(&endTime
, 0);
226 retval
= getrusage(RUSAGE_SELF
, &endUsage
);
228 timeDiff(&endTime
, &startTime
);
229 timeDiff(&endUsage
.ru_utime
, &startUsage
.ru_utime
);
230 timeDiff(&endUsage
.ru_stime
, &startUsage
.ru_stime
);
232 printf("Synchronization time:\n");
233 printf("\treal time: %ld.%06ld\n", endTime
.tv_sec
, endTime
.tv_usec
);
234 printf("\tuser time: %ld.%06ld\n", endUsage
.ru_utime
.tv_sec
,
235 endUsage
.ru_utime
.tv_usec
);
236 printf("\tsystem time: %ld.%06ld\n", endUsage
.ru_stime
.tv_sec
,
237 endUsage
.ru_stime
.tv_usec
);
243 * Calculate the elapsed time between two timeval values
246 * end: end time, result is also stored in this structure
249 static void timeDiff(struct timeval
* const end
, const struct timeval
* const start
)
251 if (end
->tv_usec
>= start
->tv_usec
)
253 end
->tv_sec
-= start
->tv_sec
;
254 end
->tv_usec
-= start
->tv_usec
;
258 end
->tv_sec
= end
->tv_sec
- start
->tv_sec
- 1;
259 end
->tv_usec
= end
->tv_usec
- start
->tv_usec
+ 1e6
;
265 * A GCompareFunc for g_slist_find_custom()
268 * a: AnalysisModule*, element's data
269 * b: char*, user data to compare against
272 * 0 if the analysis module a's name is b
274 static gint
gcfCompareAnalysis(gconstpointer a
, gconstpointer b
)
276 const AnalysisModule
* analysisModule
;
279 analysisModule
= (const AnalysisModule
*)a
;
280 name
= (const char*)b
;
282 return strncmp(analysisModule
->name
, name
, strlen(analysisModule
->name
) +
288 * A GCompareFunc for g_slist_find_custom()
291 * a: ProcessingModule*, element's data
292 * b: char*, user data to compare against
295 * 0 if the analysis module a's name is b
297 static gint
gcfCompareProcessing(gconstpointer a
, gconstpointer b
)
299 const ProcessingModule
* processingModule
;
302 processingModule
= (const ProcessingModule
*)a
;
303 name
= (const char*)b
;
305 return strncmp(processingModule
->name
, name
,
306 strlen(processingModule
->name
) + 1);
311 * A GFunc for g_queue_foreach()
313 * Concatenate analysis module names.
316 * data: AnalysisModule*
317 * user_data: GString*, concatenated names
319 static void gfAppendAnalysisName(gpointer data
, gpointer user_data
)
321 g_string_append((GString
*) user_data
, ((AnalysisModule
*) data
)->name
);
322 g_string_append((GString
*) user_data
, ", ");
326 LTTV_MODULE("sync", "Synchronize traces", \
327 "Synchronizes a traceset based on the correspondance of network events", \
328 init
, destroy
, "option")
This page took 0.073604 seconds and 5 git commands to generate.