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