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