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