1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
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;
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.
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,
28 #include "event_analysis.h"
29 #include "sync_chain_lttv.h"
31 #include "event_matching_broadcast.h"
35 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
39 // Functions common to all matching modules
40 static void initMatchingBroadcast(SyncState
* const syncState
);
41 static void destroyMatchingBroadcast(SyncState
* const syncState
);
43 static void matchEventBroadcast(SyncState
* const syncState
, Event
* const event
);
44 static GArray
* finalizeMatchingBroadcast(SyncState
* const syncState
);
45 static void printMatchingStatsBroadcast(SyncState
* const syncState
);
47 // Functions specific to this module
48 static void registerMatchingBroadcast() __attribute__((constructor (101)));
50 static void partialDestroyMatchingBroadcast(SyncState
* const syncState
);
52 static MatchingModule matchingModuleBroadcast
= {
54 .canMatch
[TCP
]= false,
56 .initMatching
= &initMatchingBroadcast
,
57 .destroyMatching
= &destroyMatchingBroadcast
,
58 .matchEvent
= &matchEventBroadcast
,
59 .finalizeMatching
= &finalizeMatchingBroadcast
,
60 .printMatchingStats
= &printMatchingStatsBroadcast
,
61 .writeMatchingGraphsPlots
= NULL
,
62 .writeMatchingGraphsOptions
= NULL
,
67 * Matching module registering function
69 static void registerMatchingBroadcast()
71 g_queue_push_tail(&matchingModules
, &matchingModuleBroadcast
);
76 * Matching init function
78 * This function is called at the beginning of a synchronization run for a set
81 * Allocate the matching specific data structures
84 * syncState container for synchronization data.
85 * This function allocates these matchingData members:
89 static void initMatchingBroadcast(SyncState
* const syncState
)
91 MatchingDataBroadcast
* matchingData
;
93 matchingData
= malloc(sizeof(MatchingDataBroadcast
));
94 syncState
->matchingData
= matchingData
;
96 matchingData
->pendingBroadcasts
= g_hash_table_new_full(&ghfDatagramKeyHash
,
97 &gefDatagramKeyEqual
, &gdnDestroyDatagramKey
, &gdnDestroyBroadcast
);
101 matchingData
->stats
= calloc(1, sizeof(MatchingStatsBroadcast
));
105 matchingData
->stats
= NULL
;
111 * Matching destroy function
113 * Free the matching specific data structures
116 * syncState container for synchronization data.
117 * This function deallocates these matchingData members:
120 static void destroyMatchingBroadcast(SyncState
* const syncState
)
122 MatchingDataBroadcast
* matchingData
;
124 matchingData
= (MatchingDataBroadcast
*) syncState
->matchingData
;
126 if (matchingData
== NULL
)
131 partialDestroyMatchingBroadcast(syncState
);
133 if (syncState
->stats
)
135 free(matchingData
->stats
);
138 free(syncState
->matchingData
);
139 syncState
->matchingData
= NULL
;
144 * Free some of the matching specific data structures
146 * This function can be called right after the events have been processed to
147 * free some data structures that are not needed for finalization.
150 * syncState container for synchronization data.
151 * This function deallocates these matchingData members:
154 static void partialDestroyMatchingBroadcast(SyncState
* const syncState
)
156 MatchingDataBroadcast
* matchingData
;
158 matchingData
= (MatchingDataBroadcast
*) syncState
->matchingData
;
160 if (matchingData
== NULL
|| matchingData
->pendingBroadcasts
== NULL
)
165 g_hash_table_destroy(matchingData
->pendingBroadcasts
);
166 matchingData
->pendingBroadcasts
= NULL
;
171 * Try to match one broadcast with previously received broadcasts (based on
172 * the addresses and the fist bytes of data they contain). Deliver them to the
173 * analysis module once a traceNb events have been accumulated for a
177 * syncState container for synchronization data.
178 * event new event to match
180 static void matchEventBroadcast(SyncState
* const syncState
, Event
* const event
)
182 MatchingDataBroadcast
* matchingData
;
184 g_assert(event
->type
== UDP
);
186 matchingData
= (MatchingDataBroadcast
*) syncState
->matchingData
;
188 if (!event
->event
.udpEvent
->unicast
)
190 if (event
->event
.udpEvent
->direction
== IN
)
192 Broadcast
* broadcast
;
193 DatagramKey
* datagramKey
;
196 if (matchingData
->stats
)
198 matchingData
->stats
->totReceive
++;
201 // s'il est déjà dans pendingBroadcasts
202 // l'ajouter à son broadcast
203 // s'il y a traceNb éléments
204 // le retirer de pending et le livrer à analysis
205 // détruire le broadcast (et ses éléments)
207 // créer un broadcast et l'ajouter à pending
210 g_hash_table_lookup_extended(matchingData
->pendingBroadcasts
,
211 event
->event
.udpEvent
->datagramKey
, (gpointer
)
212 &datagramKey
, (gpointer
) &broadcast
);
215 g_queue_push_tail(broadcast
->events
, event
);
216 if (broadcast
->events
->length
== syncState
->traceNb
)
218 g_hash_table_steal(matchingData
->pendingBroadcasts
, datagramKey
);
220 syncState
->analysisModule
->analyzeBroadcast(syncState
, broadcast
);
221 destroyBroadcast(broadcast
);
226 broadcast
= malloc(sizeof(Broadcast
));
227 broadcast
->events
= g_queue_new();
228 g_queue_push_tail(broadcast
->events
, event
);
233 if (matchingData
->stats
)
235 matchingData
->stats
->totTransmit
++;
238 event
->destroy(event
);
243 event
->destroy(event
);
250 * Call the partial matching destroyer and Obtain the factors from downstream
253 * syncState container for synchronization data.
256 * Factors[traceNb] synchronization factors for each trace
258 static GArray
* finalizeMatchingBroadcast(SyncState
* const syncState
)
260 MatchingDataBroadcast
* matchingData
;
262 matchingData
= (MatchingDataBroadcast
*) syncState
->matchingData
;
264 if (matchingData
->stats
)
266 matchingData
->stats
->totIncomplete
=
267 g_hash_table_size(matchingData
->pendingBroadcasts
);
270 partialDestroyMatchingBroadcast(syncState
);
272 return syncState
->analysisModule
->finalizeAnalysis(syncState
);
277 * Print statistics related to matching and downstream modules. Must be
278 * called after finalizeMatching.
281 * syncState container for synchronization data.
283 static void printMatchingStatsBroadcast(SyncState
* const syncState
)
285 MatchingDataBroadcast
* matchingData
;
287 if (!syncState
->stats
)
292 matchingData
= (MatchingDataBroadcast
*) syncState
->matchingData
;
294 printf("Broadcast matching stats:\n");
295 printf("\ttotal broadcasts datagrams emitted: %u\n",
296 matchingData
->stats
->totTransmit
);
297 printf("\ttotal broadcasts datagrams received: %u\n",
298 matchingData
->stats
->totReceive
);
299 printf("\ttotal broadcast groups for which all emissions were identified: %u\n",
300 matchingData
->stats
->totComplete
);
301 printf("\ttotal broadcast groups missing some emissions: %u\n",
302 matchingData
->stats
->totIncomplete
);
303 if (matchingData
->stats
->totIncomplete
> 0)
305 printf("\taverage number of broadcast datagrams received in incomplete groups: %f\n",
306 (double) (matchingData
->stats
->totReceive
-
307 matchingData
->stats
->totComplete
* syncState
->traceNb
) /
308 matchingData
->stats
->totIncomplete
);
311 if (syncState
->analysisModule
->printAnalysisStats
!= NULL
)
313 syncState
->analysisModule
->printAnalysisStats(syncState
);