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