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