Commit | Line | Data |
---|---|---|
d4721e1a | 1 | /* This file is part of the Linux Trace Toolkit viewer |
277e5b53 | 2 | * Copyright (C) 2009, 2010 Benjamin Poirier <benjamin.poirier@polymtl.ca> |
d4721e1a | 3 | * |
277e5b53 BP |
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. | |
d4721e1a | 8 | * |
277e5b53 BP |
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. | |
d4721e1a | 13 | * |
277e5b53 BP |
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/>. | |
d4721e1a BP |
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; | |
d4721e1a BP |
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); | |
0a87ec9a | 54 | static AllFactors* finalizeMatchingDistributor(SyncState* const syncState); |
d4721e1a | 55 | static void printMatchingStatsDistributor(SyncState* const syncState); |
c6356aa7 BP |
56 | static void writeMatchingTraceTraceForePlotsDistributor(SyncState* const |
57 | syncState, const unsigned int i, const unsigned int j); | |
58 | static void writeMatchingTraceTraceBackPlotsDistributor(SyncState* const | |
467066ee BP |
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); | |
c6356aa7 BP |
62 | static void writeMatchingTraceTimeForePlotsDistributor(SyncState* const |
63 | syncState, const unsigned int i, const unsigned int j); | |
64 | static void writeMatchingTraceTimeBackPlotsDistributor(SyncState* const | |
467066ee BP |
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); | |
d4721e1a BP |
68 | |
69 | // Functions specific to this module | |
d4721e1a BP |
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, | |
467066ee | 87 | .graphFunctions= { |
c6356aa7 BP |
88 | .writeTraceTraceForePlots= |
89 | &writeMatchingTraceTraceForePlotsDistributor, | |
90 | .writeTraceTraceBackPlots= | |
91 | &writeMatchingTraceTraceBackPlotsDistributor, | |
467066ee | 92 | .writeTraceTraceOptions= &writeMatchingTraceTraceOptionsDistributor, |
c6356aa7 BP |
93 | .writeTraceTimeForePlots= &writeMatchingTraceTimeForePlotsDistributor, |
94 | .writeTraceTimeBackPlots= &writeMatchingTraceTimeBackPlotsDistributor, | |
467066ee BP |
95 | .writeTraceTimeOptions= &writeMatchingTraceTimeOptionsDistributor, |
96 | }, | |
d4721e1a BP |
97 | }; |
98 | ||
99 | ||
100 | /* | |
101 | * Matching module registering function | |
102 | */ | |
2f961b65 | 103 | void registerMatchingDistributor() |
d4721e1a BP |
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 | ||
0a87ec9a | 147 | g_queue_free(matchingData->distributedModules); |
d4721e1a BP |
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 | /* | |
0a87ec9a | 171 | * Call the distributed finalization functions and return absent factors |
d4721e1a BP |
172 | * |
173 | * Args: | |
174 | * syncState container for synchronization data. | |
175 | * | |
176 | * Returns: | |
0a87ec9a | 177 | * AllFactors* synchronization factors for each trace pair |
d4721e1a | 178 | */ |
0a87ec9a | 179 | static AllFactors* finalizeMatchingDistributor(SyncState* const syncState) |
d4721e1a | 180 | { |
d4721e1a BP |
181 | MatchingDataDistributor* matchingData= syncState->matchingData; |
182 | ||
183 | g_queue_foreach(matchingData->distributedModules, &gfFinalize, NULL); | |
184 | ||
0a87ec9a | 185 | return createAllFactors(syncState->traceNb); |
d4721e1a BP |
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: | |
d4721e1a BP |
208 | * syncState: container for synchronization data |
209 | * i: first trace number | |
210 | * j: second trace number, garanteed to be larger than i | |
211 | */ | |
c6356aa7 BP |
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 | |
467066ee BP |
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, | |
c6356aa7 | 257 | graphFunctions.writeTraceTimeForePlots), i, j}); |
467066ee BP |
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 | */ | |
c6356aa7 | 269 | static void writeMatchingTraceTimeBackPlotsDistributor(SyncState* const |
467066ee BP |
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, | |
c6356aa7 | 276 | graphFunctions.writeTraceTimeBackPlots), i, j}); |
467066ee BP |
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, | |
8d7d16dd | 289 | const unsigned int i, const unsigned int j) |
d4721e1a BP |
290 | { |
291 | MatchingDataDistributor* matchingData= syncState->matchingData; | |
292 | ||
293 | g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, | |
294 | &(struct GraphAggregate) {offsetof(MatchingModule, | |
467066ee | 295 | graphFunctions.writeTraceTraceOptions), i, j}); |
d4721e1a BP |
296 | } |
297 | ||
298 | ||
299 | /* | |
300 | * Call the distributed graph options functions (when they exist). | |
301 | * | |
302 | * Args: | |
d4721e1a BP |
303 | * syncState: container for synchronization data |
304 | * i: first trace number | |
305 | * j: second trace number, garanteed to be larger than i | |
306 | */ | |
467066ee | 307 | static void writeMatchingTraceTimeOptionsDistributor(SyncState* const syncState, |
8d7d16dd | 308 | const unsigned int i, const unsigned int j) |
d4721e1a BP |
309 | { |
310 | MatchingDataDistributor* matchingData= syncState->matchingData; | |
311 | ||
312 | g_queue_foreach(matchingData->distributedModules, &gfGraphFunctionCall, | |
313 | &(struct GraphAggregate) {offsetof(MatchingModule, | |
467066ee | 314 | graphFunctions.writeTraceTimeOptions), i, j}); |
d4721e1a BP |
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 | { | |
d4721e1a BP |
395 | SyncState* parallelSS= data; |
396 | ||
b2da0724 BP |
397 | freeAllFactors(parallelSS->matchingModule->finalizeMatching(parallelSS), |
398 | parallelSS->traceNb); | |
d4721e1a BP |
399 | } |
400 | ||
401 | ||
402 | /* | |
403 | * A GFunc for g_queue_foreach() | |
404 | * | |
405 | * Args: | |
406 | * data SyncState* containing the distributed matching module | |
407 | * user_data NULL | |
408 | */ | |
409 | void gfPrintStats(gpointer data, gpointer user_data) | |
410 | { | |
411 | SyncState* parallelSS= data; | |
412 | ||
413 | if (parallelSS->matchingModule->printMatchingStats != NULL) | |
414 | { | |
415 | parallelSS->matchingModule->printMatchingStats(parallelSS); | |
416 | } | |
417 | } | |
418 | ||
419 | ||
420 | /* | |
421 | * A GFunc for g_queue_foreach() | |
422 | * | |
423 | * Call a certain matching function | |
424 | * | |
425 | * Args: | |
426 | * data SyncState* containing the distributed matching module | |
427 | * user_data size_t, | |
428 | */ | |
429 | void gfGraphFunctionCall(gpointer data, gpointer user_data) | |
430 | { | |
431 | SyncState* parallelSS= data; | |
432 | struct GraphAggregate* aggregate= user_data; | |
e072e1ab BP |
433 | typedef void (*GraphFunction)(struct _SyncState*, const unsigned int, |
434 | const unsigned int); | |
435 | GraphFunction graphFunction= *(GraphFunction*)((void*) | |
436 | parallelSS->matchingModule + (size_t) aggregate->offset); | |
d4721e1a BP |
437 | |
438 | if (graphFunction != NULL) | |
439 | { | |
8d7d16dd | 440 | graphFunction(parallelSS, aggregate->i, aggregate->j); |
d4721e1a BP |
441 | } |
442 | } |