Do not use __attribute__((constructor))
[lttv.git] / lttv / lttv / sync / event_matching_broadcast.c
CommitLineData
f10c27a8
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 <errno.h>
053b4b77 24#include <inttypes.h>
f10c27a8
BP
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
28
29#include "event_analysis.h"
2bd4b3e4 30#include "sync_chain.h"
f10c27a8
BP
31
32#include "event_matching_broadcast.h"
33
34
f10c27a8
BP
35// Functions common to all matching modules
36static void initMatchingBroadcast(SyncState* const syncState);
37static void destroyMatchingBroadcast(SyncState* const syncState);
38
39static void matchEventBroadcast(SyncState* const syncState, Event* const event);
40static GArray* finalizeMatchingBroadcast(SyncState* const syncState);
41static void printMatchingStatsBroadcast(SyncState* const syncState);
ffa21cfd
BP
42static void writeMatchingGraphsPlotsBroadcast(SyncState* const syncState, const
43 unsigned int i, const unsigned int j);
f10c27a8
BP
44
45// Functions specific to this module
f10c27a8
BP
46static void partialDestroyMatchingBroadcast(SyncState* const syncState);
47
ffa21cfd
BP
48static void openGraphDataFiles(SyncState* const syncState);
49static void writeAccuracyPoints(MatchingGraphsBroadcast* graphs, const
50 Broadcast* const broadcast);
ffa21cfd
BP
51static void closeGraphDataFiles(SyncState* const syncState);
52
53
f10c27a8
BP
54static MatchingModule matchingModuleBroadcast = {
55 .name= "broadcast",
56 .canMatch[TCP]= false,
57 .canMatch[UDP]= true,
58 .initMatching= &initMatchingBroadcast,
59 .destroyMatching= &destroyMatchingBroadcast,
60 .matchEvent= &matchEventBroadcast,
61 .finalizeMatching= &finalizeMatchingBroadcast,
62 .printMatchingStats= &printMatchingStatsBroadcast,
467066ee 63 .graphFunctions= {
c6356aa7 64 .writeTraceTimeForePlots= &writeMatchingGraphsPlotsBroadcast,
467066ee 65 }
f10c27a8
BP
66};
67
68
69/*
70 * Matching module registering function
71 */
2f961b65 72void registerMatchingBroadcast()
f10c27a8
BP
73{
74 g_queue_push_tail(&matchingModules, &matchingModuleBroadcast);
75}
76
77
78/*
79 * Matching init function
80 *
81 * This function is called at the beginning of a synchronization run for a set
82 * of traces.
83 *
84 * Allocate the matching specific data structures
85 *
86 * Args:
87 * syncState container for synchronization data.
88 * This function allocates these matchingData members:
89 * pendingBroadcasts
90 * stats
91 */
92static void initMatchingBroadcast(SyncState* const syncState)
93{
94 MatchingDataBroadcast* matchingData;
95
96 matchingData= malloc(sizeof(MatchingDataBroadcast));
97 syncState->matchingData= matchingData;
98
99 matchingData->pendingBroadcasts= g_hash_table_new_full(&ghfDatagramKeyHash,
100 &gefDatagramKeyEqual, &gdnDestroyDatagramKey, &gdnDestroyBroadcast);
101
102 if (syncState->stats)
103 {
104 matchingData->stats= calloc(1, sizeof(MatchingStatsBroadcast));
105 }
106 else
107 {
108 matchingData->stats= NULL;
109 }
ffa21cfd
BP
110
111 if (syncState->graphsStream)
112 {
113 matchingData->graphs= malloc(sizeof(MatchingGraphsBroadcast));
114 openGraphDataFiles(syncState);
115 }
116 else
117 {
118 matchingData->graphs= NULL;
119 }
f10c27a8
BP
120}
121
122
123/*
124 * Matching destroy function
125 *
126 * Free the matching specific data structures
127 *
128 * Args:
129 * syncState container for synchronization data.
130 * This function deallocates these matchingData members:
131 * stats
132 */
133static void destroyMatchingBroadcast(SyncState* const syncState)
134{
ffa21cfd
BP
135 MatchingDataBroadcast* matchingData= syncState->matchingData;
136 unsigned int i;
f10c27a8
BP
137
138 if (matchingData == NULL)
139 {
140 return;
141 }
142
143 partialDestroyMatchingBroadcast(syncState);
144
145 if (syncState->stats)
146 {
147 free(matchingData->stats);
148 }
149
ffa21cfd
BP
150 if (syncState->graphsStream)
151 {
152 for (i= 0; i < syncState->traceNb; i++)
153 {
154 free(matchingData->graphs->pointsNb[i]);
155 }
156 free(matchingData->graphs->pointsNb);
157 free(matchingData->graphs);
158 }
159
f10c27a8
BP
160 free(syncState->matchingData);
161 syncState->matchingData= NULL;
162}
163
164
165/*
166 * Free some of the matching specific data structures
167 *
168 * This function can be called right after the events have been processed to
169 * free some data structures that are not needed for finalization.
170 *
171 * Args:
172 * syncState container for synchronization data.
173 * This function deallocates these matchingData members:
174 * pendingBroadcasts
175 */
176static void partialDestroyMatchingBroadcast(SyncState* const syncState)
177{
178 MatchingDataBroadcast* matchingData;
179
180 matchingData= (MatchingDataBroadcast*) syncState->matchingData;
181
182 if (matchingData == NULL || matchingData->pendingBroadcasts == NULL)
183 {
184 return;
185 }
186
187 g_hash_table_destroy(matchingData->pendingBroadcasts);
188 matchingData->pendingBroadcasts= NULL;
ffa21cfd
BP
189
190 if (syncState->graphsStream && matchingData->graphs->accuracyPoints)
191 {
192 closeGraphDataFiles(syncState);
193 }
f10c27a8
BP
194}
195
196
197/*
198 * Try to match one broadcast with previously received broadcasts (based on
199 * the addresses and the fist bytes of data they contain). Deliver them to the
ffa21cfd 200 * analysis module once traceNb events have been accumulated for a broadcast.
f10c27a8
BP
201 *
202 * Args:
203 * syncState container for synchronization data.
204 * event new event to match
205 */
206static void matchEventBroadcast(SyncState* const syncState, Event* const event)
207{
208 MatchingDataBroadcast* matchingData;
209
210 g_assert(event->type == UDP);
211
212 matchingData= (MatchingDataBroadcast*) syncState->matchingData;
213
214 if (!event->event.udpEvent->unicast)
215 {
216 if (event->event.udpEvent->direction == IN)
217 {
218 Broadcast* broadcast;
219 DatagramKey* datagramKey;
220 gboolean result;
221
222 if (matchingData->stats)
223 {
224 matchingData->stats->totReceive++;
225 }
226
d4721e1a
BP
227 /* if event in pendingBroadcasts:
228 * add it to its broadcast
229 * if this broadcast has traceNb events:
230 * remove it from pending and deliver it to analysis
231 * destroy the broadcast (and its elements)
232 * else:
233 * create a broadcast and add it to pending
234 */
f10c27a8
BP
235
236 result=
237 g_hash_table_lookup_extended(matchingData->pendingBroadcasts,
238 event->event.udpEvent->datagramKey, (gpointer)
239 &datagramKey, (gpointer) &broadcast);
240 if (result)
241 {
242 g_queue_push_tail(broadcast->events, event);
243 if (broadcast->events->length == syncState->traceNb)
244 {
2bd4b3e4
BP
245 if (matchingData->stats)
246 {
247 matchingData->stats->totComplete++;
248 }
249
f10c27a8
BP
250 g_hash_table_steal(matchingData->pendingBroadcasts, datagramKey);
251 free(datagramKey);
252 syncState->analysisModule->analyzeBroadcast(syncState, broadcast);
ffa21cfd
BP
253
254 if (syncState->graphsStream)
255 {
256 writeAccuracyPoints(matchingData->graphs, broadcast);
257 }
f10c27a8
BP
258 destroyBroadcast(broadcast);
259 }
260 }
261 else
262 {
263 broadcast= malloc(sizeof(Broadcast));
264 broadcast->events= g_queue_new();
265 g_queue_push_tail(broadcast->events, event);
2bd4b3e4
BP
266
267 datagramKey= malloc(sizeof(DatagramKey));
268 *datagramKey= *event->event.udpEvent->datagramKey;
269
270 g_hash_table_insert(matchingData->pendingBroadcasts,
271 datagramKey, broadcast);
f10c27a8
BP
272 }
273 }
274 else
275 {
276 if (matchingData->stats)
277 {
278 matchingData->stats->totTransmit++;
279 }
280
281 event->destroy(event);
282 }
283 }
284 else
285 {
286 event->destroy(event);
287 }
288
289}
290
291
292/*
293 * Call the partial matching destroyer and Obtain the factors from downstream
294 *
295 * Args:
296 * syncState container for synchronization data.
297 *
298 * Returns:
299 * Factors[traceNb] synchronization factors for each trace
300 */
301static GArray* finalizeMatchingBroadcast(SyncState* const syncState)
302{
303 MatchingDataBroadcast* matchingData;
304
305 matchingData= (MatchingDataBroadcast*) syncState->matchingData;
306
307 if (matchingData->stats)
308 {
309 matchingData->stats->totIncomplete=
310 g_hash_table_size(matchingData->pendingBroadcasts);
311 }
312
313 partialDestroyMatchingBroadcast(syncState);
314
315 return syncState->analysisModule->finalizeAnalysis(syncState);
316}
317
318
319/*
d6ee5003
BP
320 * Print statistics related to matching. Must be called after
321 * finalizeMatching.
f10c27a8
BP
322 *
323 * Args:
324 * syncState container for synchronization data.
325 */
326static void printMatchingStatsBroadcast(SyncState* const syncState)
327{
328 MatchingDataBroadcast* matchingData;
329
330 if (!syncState->stats)
331 {
332 return;
333 }
f10c27a8
BP
334 matchingData= (MatchingDataBroadcast*) syncState->matchingData;
335
336 printf("Broadcast matching stats:\n");
337 printf("\ttotal broadcasts datagrams emitted: %u\n",
338 matchingData->stats->totTransmit);
339 printf("\ttotal broadcasts datagrams received: %u\n",
340 matchingData->stats->totReceive);
76be6fc2 341 printf("\ttotal broadcast groups for which all receptions were identified: %u\n",
f10c27a8 342 matchingData->stats->totComplete);
76be6fc2 343 printf("\ttotal broadcast groups missing some receptions: %u\n",
f10c27a8
BP
344 matchingData->stats->totIncomplete);
345 if (matchingData->stats->totIncomplete > 0)
346 {
347 printf("\taverage number of broadcast datagrams received in incomplete groups: %f\n",
348 (double) (matchingData->stats->totReceive -
349 matchingData->stats->totComplete * syncState->traceNb) /
350 matchingData->stats->totIncomplete);
351 }
f10c27a8 352}
ffa21cfd
BP
353
354
355/*
356 * Create and open files used to store accuracy points to genereate graphs.
357 * Allocate and populate array to store file pointers and counters.
358 *
359 * Args:
360 * syncState: container for synchronization data
361 */
362static void openGraphDataFiles(SyncState* const syncState)
363{
364 unsigned int i, j;
365 int retval;
366 char* cwd;
367 char name[36];
368 MatchingGraphsBroadcast* graphs= ((MatchingDataBroadcast*)
369 syncState->matchingData)->graphs;
370
1d597550 371 cwd= changeToGraphsDir(syncState->graphsDir);
ffa21cfd
BP
372
373 graphs->accuracyPoints= malloc(syncState->traceNb * sizeof(FILE**));
374 graphs->pointsNb= malloc(syncState->traceNb * sizeof(unsigned int*));
375 for (i= 0; i < syncState->traceNb; i++)
376 {
377 graphs->accuracyPoints[i]= malloc(i * sizeof(FILE*));
378 graphs->pointsNb[i]= calloc(i, sizeof(unsigned int));
379 for (j= 0; j < i; j++)
380 {
381 retval= snprintf(name, sizeof(name),
382 "matching_broadcast-%03u_and_%03u.data", j, i);
383 g_assert_cmpint(retval, <=, sizeof(name) - 1);
384 if ((graphs->accuracyPoints[i][j]= fopen(name, "w")) == NULL)
385 {
386 g_error(strerror(errno));
387 }
388 }
389 }
390
391 retval= chdir(cwd);
392 if (retval == -1)
393 {
394 g_error(strerror(errno));
395 }
396 free(cwd);
397}
398
399
400/*
401 * Calculate and write points used to generate graphs
402 *
403 * Args:
404 * graphs: structure containing array of file pointers and counters
405 * broadcast: broadcast for which to write the points
406 */
407static void writeAccuracyPoints(MatchingGraphsBroadcast* graphs, const
408 Broadcast* const broadcast)
409{
410 unsigned int i, j;
411 GArray* events;
412 unsigned int eventNb= broadcast->events->length;
413
414 events= g_array_sized_new(FALSE, FALSE, sizeof(Event*), eventNb);
66eaf2eb 415 g_queue_foreach(broadcast->events, &gfAddEventToArray, events);
ffa21cfd
BP
416
417 for (i= 0; i < eventNb; i++)
418 {
419 for (j= 0; j < eventNb; j++)
420 {
421 Event* eventI= g_array_index(events, Event*, i), * eventJ=
422 g_array_index(events, Event*, j);
423
424 if (eventI->traceNum < eventJ->traceNum)
425 {
426 fprintf(graphs->accuracyPoints[eventJ->traceNum][eventI->traceNum],
053b4b77 427 "%20" PRIu64 " %20.9f\n", eventI->cpuTime,
467066ee 428 wallTimeSub(&eventJ->wallTime, &eventI->wallTime));
ffa21cfd
BP
429 graphs->pointsNb[eventJ->traceNum][eventI->traceNum]++;
430 }
431 }
432 }
ffa21cfd 433
66eaf2eb 434 g_array_free(events, TRUE);
ffa21cfd
BP
435}
436
437
438/*
439 * Close files used to store accuracy points to genereate graphs. Deallocate
440 * array to store file pointers (but not array for counters).
441 *
442 * Args:
443 * syncState: container for synchronization data
444 */
445static void closeGraphDataFiles(SyncState* const syncState)
446{
447 unsigned int i, j;
448 MatchingGraphsBroadcast* graphs= ((MatchingDataBroadcast*)
449 syncState->matchingData)->graphs;
450 int retval;
451
452 if (graphs->accuracyPoints == NULL)
453 {
454 return;
455 }
456
457 for (i= 0; i < syncState->traceNb; i++)
458 {
459 for (j= 0; j < i; j++)
460 {
461 retval= fclose(graphs->accuracyPoints[i][j]);
462 if (retval != 0)
463 {
464 g_error(strerror(errno));
465 }
466 }
467 free(graphs->accuracyPoints[i]);
468 }
469 free(graphs->accuracyPoints);
470
471 graphs->accuracyPoints= NULL;
472}
473
474
475/*
476 * Write the matching-specific graph lines in the gnuplot script.
477 *
478 * Args:
479 * syncState: container for synchronization data
480 * i: first trace number
481 * j: second trace number, garanteed to be larger than i
482 */
483static void writeMatchingGraphsPlotsBroadcast(SyncState* const syncState, const
484 unsigned int i, const unsigned int j)
485{
486 if (((MatchingDataBroadcast*)
487 syncState->matchingData)->graphs->pointsNb[j][i])
488 {
489 fprintf(syncState->graphsStream,
490 "\t\"matching_broadcast-%03d_and_%03d.data\" "
c5571851 491 "title \"Broadcast differential delays\" with points "
ffa21cfd
BP
492 "linecolor rgb \"black\" pointtype 6 pointsize 2, \\\n", i,
493 j);
494 }
495}
This page took 0.043524 seconds and 4 git commands to generate.