Add a module to distribute messages to many analysis modules
[lttv.git] / lttv / lttv / sync / event_matching_distributor.c
CommitLineData
d4721e1a
BP
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
33struct InitAggregate
34{
35 SyncState* syncState;
36 GQueue* matchingModules;
37};
38
39
40struct 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
51static void initMatchingDistributor(SyncState* const syncState);
52static void destroyMatchingDistributor(SyncState* const syncState);
53
54static void matchEventDistributor(SyncState* const syncState, Event* const
55 event);
56static GArray* finalizeMatchingDistributor(SyncState* const syncState);
57static void printMatchingStatsDistributor(SyncState* const syncState);
58static void writeMatchingGraphsPlotsDistributor(FILE* stream, SyncState* const
59 syncState, const unsigned int i, const unsigned int j);
60static void writeMatchingGraphsOptionsDistributor(FILE* stream, SyncState*
61 const syncState, const unsigned int i, const unsigned int j);
62
63// Functions specific to this module
64static void registerMatchingDistributor() __attribute__((constructor (101)));
65
66void gfInitModule(gpointer data, gpointer user_data);
67void gfDestroyModule(gpointer data, gpointer user_data);
68void gfMatchEvent(gpointer data, gpointer user_data);
69void gfFinalize(gpointer data, gpointer user_data);
70void gfPrintStats(gpointer data, gpointer user_data);
71void gfGraphFunctionCall(gpointer data, gpointer user_data);
72
73
74static 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 */
91static 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 */
108static 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 */
129static 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 */
149static 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 */
167static 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 */
198static 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 */
215static 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 */
235static 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 */
255void 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 */
284void 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 */
300void 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 */
321void 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 */
338void 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 */
358void 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.035829 seconds and 4 git commands to generate.