6ea6c0fd95f3c1add42284e69161448e0c1b742d
[lttv.git] / lttv / lttv / sync / event_matching_distributor.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <stddef.h>
25 #include <string.h>
26
27 #include "event_analysis.h"
28 #include "sync_chain.h"
29
30 #include "event_matching_distributor.h"
31
32
33 struct InitAggregate
34 {
35 SyncState* syncState;
36 GQueue* matchingModules;
37 };
38
39
40 struct GraphAggregate
41 {
42 /* Offset whithin Matching module of the field* containing the function
43 * pointer */
44 size_t offset;
45 unsigned int i, j;
46 };
47
48
49 // Functions common to all matching modules
50 static void initMatchingDistributor(SyncState* const syncState);
51 static void destroyMatchingDistributor(SyncState* const syncState);
52
53 static void matchEventDistributor(SyncState* const syncState, Event* const
54 event);
55 static GArray* finalizeMatchingDistributor(SyncState* const syncState);
56 static void printMatchingStatsDistributor(SyncState* const syncState);
57 static void writeMatchingTraceTraceForePlotsDistributor(SyncState* const
58 syncState, const unsigned int i, const unsigned int j);
59 static void writeMatchingTraceTraceBackPlotsDistributor(SyncState* const
60 syncState, const unsigned int i, const unsigned int j);
61 static void writeMatchingTraceTraceOptionsDistributor(SyncState* const
62 syncState, const unsigned int i, const unsigned int j);
63 static void writeMatchingTraceTimeForePlotsDistributor(SyncState* const
64 syncState, const unsigned int i, const unsigned int j);
65 static void writeMatchingTraceTimeBackPlotsDistributor(SyncState* const
66 syncState, const unsigned int i, const unsigned int j);
67 static void writeMatchingTraceTimeOptionsDistributor(SyncState* const
68 syncState, const unsigned int i, const unsigned int j);
69
70 // Functions specific to this module
71 void gfInitModule(gpointer data, gpointer user_data);
72 void gfDestroyModule(gpointer data, gpointer user_data);
73 void gfMatchEvent(gpointer data, gpointer user_data);
74 void gfFinalize(gpointer data, gpointer user_data);
75 void gfPrintStats(gpointer data, gpointer user_data);
76 void gfGraphFunctionCall(gpointer data, gpointer user_data);
77
78
79 static MatchingModule matchingModuleDistributor = {
80 .name= "distributor",
81 .canMatch[TCP]= true,
82 .canMatch[UDP]= true,
83 .initMatching= &initMatchingDistributor,
84 .destroyMatching= &destroyMatchingDistributor,
85 .matchEvent= &matchEventDistributor,
86 .finalizeMatching= &finalizeMatchingDistributor,
87 .printMatchingStats= &printMatchingStatsDistributor,
88 .graphFunctions= {
89 .writeTraceTraceForePlots=
90 &writeMatchingTraceTraceForePlotsDistributor,
91 .writeTraceTraceBackPlots=
92 &writeMatchingTraceTraceBackPlotsDistributor,
93 .writeTraceTraceOptions= &writeMatchingTraceTraceOptionsDistributor,
94 .writeTraceTimeForePlots= &writeMatchingTraceTimeForePlotsDistributor,
95 .writeTraceTimeBackPlots= &writeMatchingTraceTimeBackPlotsDistributor,
96 .writeTraceTimeOptions= &writeMatchingTraceTimeOptionsDistributor,
97 },
98 };
99
100
101 /*
102 * Matching module registering function
103 */
104 void registerMatchingDistributor()
105 {
106 g_queue_push_tail(&matchingModules, &matchingModuleDistributor);
107 }
108
109
110 /*
111 * Matching init function
112 *
113 * This function is called at the beginning of a synchronization run for a set
114 * of traces.
115 *
116 * Build the list and initialize other matching Modules
117 *
118 * Args:
119 * syncState container for synchronization data.
120 */
121 static void initMatchingDistributor(SyncState* const syncState)
122 {
123 MatchingDataDistributor* matchingData;
124
125 matchingData= malloc(sizeof(MatchingDataDistributor));
126 syncState->matchingData= matchingData;
127
128 matchingData->distributedModules= g_queue_new();
129 g_queue_foreach(&matchingModules, &gfInitModule, &(struct InitAggregate)
130 {syncState, matchingData->distributedModules});
131 }
132
133
134 /*
135 * Matching destroy function
136 *
137 * Destroy other modules and free the matching specific data structures
138 *
139 * Args:
140 * syncState container for synchronization data.
141 */
142 static void destroyMatchingDistributor(SyncState* const syncState)
143 {
144 MatchingDataDistributor* matchingData= syncState->matchingData;
145
146 g_queue_foreach(matchingData->distributedModules, &gfDestroyModule, NULL);
147
148 g_queue_clear(matchingData->distributedModules);
149 free(syncState->matchingData);
150 syncState->matchingData= NULL;
151 }
152
153
154
155 /*
156 * Copy event and distribute to matching modules
157 *
158 * Args:
159 * syncState container for synchronization data.
160 * event new event to match
161 */
162 static void matchEventDistributor(SyncState* const syncState, Event* const event)
163 {
164 MatchingDataDistributor* matchingData= syncState->matchingData;
165
166 g_queue_foreach(matchingData->distributedModules, &gfMatchEvent, event);
167 event->destroy(event);
168 }
169
170
171 /*
172 * Call the distributed finalization functions and return identity factors
173 *
174 * Args:
175 * syncState container for synchronization data.
176 *
177 * Returns:
178 * Factors[traceNb] identity factors for each trace
179 */
180 static GArray* finalizeMatchingDistributor(SyncState* const syncState)
181 {
182 GArray* factors;
183 unsigned int i;
184 MatchingDataDistributor* matchingData= syncState->matchingData;
185
186 g_queue_foreach(matchingData->distributedModules, &gfFinalize, NULL);
187
188 factors= g_array_sized_new(FALSE, FALSE, sizeof(Factors),
189 syncState->traceNb);
190 g_array_set_size(factors, syncState->traceNb);
191 for (i= 0; i < syncState->traceNb; i++)
192 {
193 Factors* e;
194
195 e= &g_array_index(factors, Factors, i);
196 e->drift= 1.;
197 e->offset= 0.;
198 }
199
200 return factors;
201 }
202
203
204 /*
205 * Call the distributed statistics functions (when they exist). Must be called
206 * after finalizeMatching.
207 *
208 * Args:
209 * syncState container for synchronization data.
210 */
211 static void printMatchingStatsDistributor(SyncState* const syncState)
212 {
213 MatchingDataDistributor* matchingData= syncState->matchingData;
214
215 g_queue_foreach(matchingData->distributedModules, &gfPrintStats, NULL);
216 }
217
218
219 /*
220 * Call the distributed graph lines functions (when they exist).
221 *
222 * Args:
223 * syncState: container for synchronization data
224 * i: first trace number
225 * j: second trace number, garanteed to be larger than i
226 */
227 static void writeMatchingTraceTraceForePlotsDistributor(SyncState* const
228 syncState, const unsigned int i, const unsigned int j)
229 {
230 MatchingDataDistributor* matchingData= syncState->matchingData;
231
232 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
233 &(struct GraphAggregate) {offsetof(MatchingModule,
234 graphFunctions.writeTraceTraceForePlots), i, j});
235 }
236
237
238 /*
239 * Call the distributed graph lines functions (when they exist).
240 *
241 * Args:
242 * syncState: container for synchronization data
243 * i: first trace number
244 * j: second trace number, garanteed to be larger than i
245 */
246 static void writeMatchingTraceTraceBackPlotsDistributor(SyncState* const
247 syncState, const unsigned int i, const unsigned int j)
248 {
249 MatchingDataDistributor* matchingData= syncState->matchingData;
250
251 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
252 &(struct GraphAggregate) {offsetof(MatchingModule,
253 graphFunctions.writeTraceTraceBackPlots), i, j});
254 }
255
256
257 /*
258 * Call the distributed graph lines functions (when they exist).
259 *
260 * Args:
261 * syncState: container for synchronization data
262 * i: first trace number
263 * j: second trace number, garanteed to be larger than i
264 */
265 static void writeMatchingTraceTimeForePlotsDistributor(SyncState* const
266 syncState, const unsigned int i, const unsigned int j)
267 {
268 MatchingDataDistributor* matchingData= syncState->matchingData;
269
270 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
271 &(struct GraphAggregate) {offsetof(MatchingModule,
272 graphFunctions.writeTraceTimeForePlots), i, j});
273 }
274
275
276 /*
277 * Call the distributed graph lines functions (when they exist).
278 *
279 * Args:
280 * syncState: container for synchronization data
281 * i: first trace number
282 * j: second trace number, garanteed to be larger than i
283 */
284 static void writeMatchingTraceTimeBackPlotsDistributor(SyncState* const
285 syncState, const unsigned int i, const unsigned int j)
286 {
287 MatchingDataDistributor* matchingData= syncState->matchingData;
288
289 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
290 &(struct GraphAggregate) {offsetof(MatchingModule,
291 graphFunctions.writeTraceTimeBackPlots), i, j});
292 }
293
294
295 /*
296 * Call the distributed graph options functions (when they exist).
297 *
298 * Args:
299 * syncState: container for synchronization data
300 * i: first trace number
301 * j: second trace number, garanteed to be larger than i
302 */
303 static void writeMatchingTraceTraceOptionsDistributor(SyncState* const syncState,
304 const unsigned int i, const unsigned int j)
305 {
306 MatchingDataDistributor* matchingData= syncState->matchingData;
307
308 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
309 &(struct GraphAggregate) {offsetof(MatchingModule,
310 graphFunctions.writeTraceTraceOptions), i, j});
311 }
312
313
314 /*
315 * Call the distributed graph options functions (when they exist).
316 *
317 * Args:
318 * syncState: container for synchronization data
319 * i: first trace number
320 * j: second trace number, garanteed to be larger than i
321 */
322 static void writeMatchingTraceTimeOptionsDistributor(SyncState* const syncState,
323 const unsigned int i, const unsigned int j)
324 {
325 MatchingDataDistributor* matchingData= syncState->matchingData;
326
327 g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall,
328 &(struct GraphAggregate) {offsetof(MatchingModule,
329 graphFunctions.writeTraceTimeOptions), i, j});
330 }
331
332
333 /*
334 * A GFunc for g_queue_foreach()
335 *
336 * Add and initialize matching module
337 *
338 * Args:
339 * data MatchingModule*, module to add
340 * user_data InitAggregate*
341 */
342 void gfInitModule(gpointer data, gpointer user_data)
343 {
344 SyncState* parallelSS;
345 struct InitAggregate* aggregate= user_data;
346 MatchingModule* matchingModule= data;
347
348 if (strcmp(matchingModule->name, matchingModuleDistributor.name) == 0)
349 {
350 return;
351 }
352
353 parallelSS= malloc(sizeof(SyncState));
354 memcpy(parallelSS, aggregate->syncState, sizeof(SyncState));
355 g_queue_push_tail(aggregate->matchingModules, parallelSS);
356
357 parallelSS->matchingModule= matchingModule;
358 parallelSS->matchingModule->initMatching(parallelSS);
359 }
360
361
362 /*
363 * A GFunc for g_queue_foreach()
364 *
365 * Destroy and remove matching module
366 *
367 * Args:
368 * data SyncState* containing the module to destroy
369 * user_data NULL
370 */
371 void gfDestroyModule(gpointer data, gpointer user_data)
372 {
373 SyncState* parallelSS= data;
374
375 parallelSS->matchingModule->destroyMatching(parallelSS);
376 free(parallelSS);
377 }
378
379
380 /*
381 * A GFunc for g_queue_foreach()
382 *
383 * Args:
384 * data SyncState* containing the distributed matching module
385 * user_data Event* original event
386 */
387 void gfMatchEvent(gpointer data, gpointer user_data)
388 {
389 SyncState* parallelSS= data;
390 const Event* event= user_data;
391 Event* newEvent;
392
393 if (parallelSS->matchingModule->canMatch[event->type])
394 {
395 event->copy(event, &newEvent);
396 parallelSS->matchingModule->matchEvent(parallelSS, newEvent);
397 }
398 }
399
400
401 /*
402 * A GFunc for g_queue_foreach()
403 *
404 * Args:
405 * data SyncState* containing the distributed matching module
406 * user_data NULL
407 */
408 void gfFinalize(gpointer data, gpointer user_data)
409 {
410 GArray* factors;
411 SyncState* parallelSS= data;
412
413 factors= parallelSS->matchingModule->finalizeMatching(parallelSS);
414 g_array_free(factors, TRUE);
415 }
416
417
418 /*
419 * A GFunc for g_queue_foreach()
420 *
421 * Args:
422 * data SyncState* containing the distributed matching module
423 * user_data NULL
424 */
425 void gfPrintStats(gpointer data, gpointer user_data)
426 {
427 SyncState* parallelSS= data;
428
429 if (parallelSS->matchingModule->printMatchingStats != NULL)
430 {
431 parallelSS->matchingModule->printMatchingStats(parallelSS);
432 }
433 }
434
435
436 /*
437 * A GFunc for g_queue_foreach()
438 *
439 * Call a certain matching function
440 *
441 * Args:
442 * data SyncState* containing the distributed matching module
443 * user_data size_t,
444 */
445 void gfGraphFunctionCall(gpointer data, gpointer user_data)
446 {
447 SyncState* parallelSS= data;
448 struct GraphAggregate* aggregate= user_data;
449 typedef void (*GraphFunction)(struct _SyncState*, const unsigned int,
450 const unsigned int);
451 GraphFunction graphFunction= *(GraphFunction*)((void*)
452 parallelSS->matchingModule + (size_t) aggregate->offset);
453
454 if (graphFunction != NULL)
455 {
456 graphFunction(parallelSS, aggregate->i, aggregate->j);
457 }
458 }
This page took 0.037816 seconds and 3 git commands to generate.