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