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