Do not use __attribute__((constructor))
[lttv.git] / lttv / lttv / sync / event_processing_lttng_standard.c
CommitLineData
70407e86
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#define _ISOC99_SOURCE
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
70407e86
BP
25#include <math.h>
26#include <netinet/in.h>
2f076594 27#include <stdarg.h>
70407e86
BP
28#include <stdint.h>
29#include <stdlib.h>
f6691532 30#include <string.h>
70407e86 31
2bd4b3e4 32#include "sync_chain.h"
10341d26 33#include "event_processing_lttng_common.h"
70407e86 34
10341d26 35#include "event_processing_lttng_standard.h"
70407e86 36
2bd5afbb
BP
37/* IPv4 Ethertype, taken from <linux/if_ether.h>, unlikely to change as it's
38 * defined by IANA: http://www.iana.org/assignments/ethernet-numbers
39 */
40#define ETH_P_IP 0x0800
41
70407e86 42
08365995 43// Functions common to all processing modules
2f076594 44static void initProcessingLTTVStandard(SyncState* const syncState, ...);
70407e86
BP
45static void destroyProcessingLTTVStandard(SyncState* const syncState);
46
47static void finalizeProcessingLTTVStandard(SyncState* const syncState);
48static void printProcessingStatsLTTVStandard(SyncState* const syncState);
66eaf2eb
BP
49static void writeProcessingGraphVariablesLTTVStandard(SyncState* const
50 syncState, const unsigned int i);
467066ee
BP
51static void writeProcessingTraceTraceOptionsLTTVStandard(SyncState* const
52 syncState, const unsigned int i, const unsigned int j);
53static void writeProcessingTraceTimeOptionsLTTVStandard(SyncState* const
8d7d16dd 54 syncState, const unsigned int i, const unsigned int j);
70407e86
BP
55
56// Functions specific to this module
70407e86
BP
57static gboolean processEventLTTVStandard(void* hookData, void* callData);
58static void partialDestroyProcessingLTTVStandard(SyncState* const syncState);
59
60
61static ProcessingModule processingModuleLTTVStandard = {
62 .name= "LTTV-standard",
63 .initProcessing= &initProcessingLTTVStandard,
64 .destroyProcessing= &destroyProcessingLTTVStandard,
65 .finalizeProcessing= &finalizeProcessingLTTVStandard,
66 .printProcessingStats= &printProcessingStatsLTTVStandard,
467066ee 67 .graphFunctions= {
66eaf2eb 68 .writeVariables= &writeProcessingGraphVariablesLTTVStandard,
467066ee
BP
69 .writeTraceTraceOptions= &writeProcessingTraceTraceOptionsLTTVStandard,
70 .writeTraceTimeOptions= &writeProcessingTraceTimeOptionsLTTVStandard,
71 },
70407e86
BP
72};
73
74
70407e86
BP
75/*
76 * Processing Module registering function
77 */
2f961b65 78void registerProcessingLTTVStandard()
70407e86
BP
79{
80 g_queue_push_tail(&processingModules, &processingModuleLTTVStandard);
81
82 createQuarks();
83}
84
85
86/*
87 * Allocate and initialize data structures for synchronizing a traceset.
88 * Register event hooks.
89 *
90 * Args:
91 * syncState: container for synchronization data.
92 * This function allocates these processingData members:
93 * traceNumTable
94 * pendingRecv
95 * hookListList
96 * stats
2f076594 97 * traceSetContext: LttvTracesetContext*, set of LTTV traces
70407e86 98 */
2f076594 99static void initProcessingLTTVStandard(SyncState* const syncState, ...)
70407e86
BP
100{
101 unsigned int i;
102 ProcessingDataLTTVStandard* processingData;
2f076594 103 va_list ap;
70407e86
BP
104
105 processingData= malloc(sizeof(ProcessingDataLTTVStandard));
106 syncState->processingData= processingData;
2f076594
BP
107 va_start(ap, syncState);
108 processingData->traceSetContext= va_arg(ap, LttvTracesetContext*);
109 va_end(ap);
09857093
BP
110 syncState->traceNb=
111 lttv_traceset_number(processingData->traceSetContext->ts);
112 processingData->hookListList= g_array_sized_new(FALSE, FALSE,
113 sizeof(GArray*), syncState->traceNb);
70407e86 114
09857093
BP
115 processingData->traceNumTable= g_hash_table_new(&g_direct_hash, NULL);
116 for(i= 0; i < syncState->traceNb; i++)
70407e86 117 {
09857093 118 g_hash_table_insert(processingData->traceNumTable,
053b4b77
BP
119 processingData->traceSetContext->traces[i]->t,
120 GUINT_TO_POINTER(i));
70407e86
BP
121 }
122
70407e86
BP
123 processingData->pendingRecv= malloc(sizeof(GHashTable*) *
124 syncState->traceNb);
70407e86
BP
125 for(i= 0; i < syncState->traceNb; i++)
126 {
09857093
BP
127 processingData->pendingRecv[i]= g_hash_table_new_full(&g_direct_hash,
128 NULL, NULL, &gdnDestroyEvent);
129 }
130
131 if (syncState->stats)
132 {
133 processingData->stats= calloc(1, sizeof(ProcessingStatsLTTVStandard));
134 }
135 else
136 {
137 processingData->stats= NULL;
70407e86
BP
138 }
139
1633c5a5
BP
140 if (syncState->graphsStream)
141 {
142 processingData->graphs= malloc(syncState->traceNb *
143 sizeof(ProcessingGraphsLTTVStandard));
144
145 for(i= 0; i < syncState->traceNb; i++)
146 {
2f076594 147 LttTrace* traceI= processingData->traceSetContext->traces[i]->t;
1633c5a5
BP
148
149 processingData->graphs[i].startFreq= traceI->start_freq;
150 processingData->graphs[i].freqScale= traceI->freq_scale;
151 }
152 }
153 else
154 {
155 processingData->graphs= NULL;
156 }
157
2f076594
BP
158 registerHooks(processingData->hookListList,
159 processingData->traceSetContext, &processEventLTTVStandard, syncState,
f6691532 160 syncState->matchingModule->canMatch);
70407e86
BP
161}
162
163
164/*
165 * Call the partial processing destroyer, obtain and adjust the factors from
166 * downstream
167 *
168 * Args:
169 * syncState container for synchronization data.
170 */
171static void finalizeProcessingLTTVStandard(SyncState* const syncState)
172{
173 unsigned int i;
174 GArray* factors;
175 double minOffset, minDrift;
176 unsigned int refFreqTrace;
177 ProcessingDataLTTVStandard* processingData;
178
179 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
180
181 partialDestroyProcessingLTTVStandard(syncState);
182
183 factors= syncState->matchingModule->finalizeMatching(syncState);
184
185 /* The offsets are adjusted so the lowest one is 0. This is done because
186 * of a Lttv specific limitation: events cannot have negative times. By
187 * having non-negative offsets, events cannot be moved backwards to
188 * negative times.
189 */
190 minOffset= 0;
191 for (i= 0; i < syncState->traceNb; i++)
192 {
193 minOffset= MIN(g_array_index(factors, Factors, i).offset, minOffset);
194 }
195
196 for (i= 0; i < syncState->traceNb; i++)
197 {
198 g_array_index(factors, Factors, i).offset-= minOffset;
199 }
200
201 /* Because the timestamps are corrected at the TSC level (not at the
202 * LttTime level) all trace frequencies must be made equal. We choose to
203 * use the frequency of the system with the lowest drift
204 */
205 minDrift= INFINITY;
206 refFreqTrace= 0;
207 for (i= 0; i < syncState->traceNb; i++)
208 {
209 if (g_array_index(factors, Factors, i).drift < minDrift)
210 {
211 minDrift= g_array_index(factors, Factors, i).drift;
212 refFreqTrace= i;
213 }
214 }
215 g_assert(syncState->traceNb == 0 || minDrift != INFINITY);
216
217 // Write the factors to the LttTrace structures
218 for (i= 0; i < syncState->traceNb; i++)
219 {
220 LttTrace* t;
221 Factors* traceFactors;
222
223 t= processingData->traceSetContext->traces[i]->t;
224 traceFactors= &g_array_index(factors, Factors, i);
225
226 t->drift= traceFactors->drift;
227 t->offset= traceFactors->offset;
228 t->start_freq=
229 processingData->traceSetContext->traces[refFreqTrace]->t->start_freq;
230 t->freq_scale=
231 processingData->traceSetContext->traces[refFreqTrace]->t->freq_scale;
232 t->start_time_from_tsc =
233 ltt_time_from_uint64(tsc_to_uint64(t->freq_scale, t->start_freq,
234 t->drift * t->start_tsc + t->offset));
235 }
236
237 g_array_free(factors, TRUE);
238
239 lttv_traceset_context_compute_time_span(processingData->traceSetContext,
240 &processingData->traceSetContext->time_span);
241
d5b038ec 242 g_debug("traceset start %ld.%09ld end %ld.%09ld",
70407e86
BP
243 processingData->traceSetContext->time_span.start_time.tv_sec,
244 processingData->traceSetContext->time_span.start_time.tv_nsec,
245 processingData->traceSetContext->time_span.end_time.tv_sec,
246 processingData->traceSetContext->time_span.end_time.tv_nsec);
70407e86
BP
247}
248
249
250/*
d6ee5003
BP
251 * Print statistics related to processing Must be called after
252 * finalizeProcessing.
70407e86
BP
253 *
254 * Args:
255 * syncState container for synchronization data.
256 */
257static void printProcessingStatsLTTVStandard(SyncState* const syncState)
258{
70407e86
BP
259 ProcessingDataLTTVStandard* processingData;
260
261 if (!syncState->stats)
262 {
263 return;
264 }
265
266 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
267
268 printf("LTTV processing stats:\n");
269 printf("\treceived frames: %d\n", processingData->stats->totRecv);
270 printf("\treceived frames that are IP: %d\n",
271 processingData->stats->totRecvIp);
f6691532
BP
272 if (syncState->matchingModule->canMatch[TCP])
273 {
274 printf("\treceived and processed packets that are TCP: %d\n",
275 processingData->stats->totRecvTCP);
276 }
277 if (syncState->matchingModule->canMatch[UDP])
278 {
279 printf("\treceived and processed packets that are UDP: %d\n",
280 processingData->stats->totRecvUDP);
281 }
282 if (syncState->matchingModule->canMatch[TCP])
283 {
284 printf("\tsent packets that are TCP: %d\n",
285 processingData->stats->totOutE);
286 }
70407e86
BP
287}
288
289
290/*
291 * Unregister event hooks. Deallocate processingData.
292 *
293 * Args:
294 * syncState: container for synchronization data.
295 * This function deallocates these processingData members:
296 * stats
297 */
298static void destroyProcessingLTTVStandard(SyncState* const syncState)
299{
300 ProcessingDataLTTVStandard* processingData;
301
302 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
303
304 if (processingData == NULL)
305 {
306 return;
307 }
308
309 partialDestroyProcessingLTTVStandard(syncState);
310
311 if (syncState->stats)
312 {
313 free(processingData->stats);
314 }
315
1633c5a5
BP
316 if (syncState->graphsStream)
317 {
318 free(processingData->graphs);
319 }
320
70407e86
BP
321 free(syncState->processingData);
322 syncState->processingData= NULL;
323}
324
325
326/*
327 * Unregister event hooks. Deallocate some of processingData.
328 *
329 * This function can be called right after the events have been processed to
330 * free some data structures that are not needed for finalization.
331 *
332 * Args:
333 * syncState: container for synchronization data.
334 * This function deallocates these members:
335 * traceNumTable
336 * hookListList
337 * pendingRecv
338 */
339static void partialDestroyProcessingLTTVStandard(SyncState* const syncState)
340{
341 unsigned int i;
342 ProcessingDataLTTVStandard* processingData;
343
344 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
345
346 if (processingData == NULL || processingData->traceNumTable == NULL)
347 {
348 return;
349 }
350
351 g_hash_table_destroy(processingData->traceNumTable);
352 processingData->traceNumTable= NULL;
353
354 for(i= 0; i < syncState->traceNb; i++)
355 {
356
d5b038ec 357 g_debug("Cleaning up pendingRecv list");
70407e86
BP
358 g_hash_table_destroy(processingData->pendingRecv[i]);
359 }
360 free(processingData->pendingRecv);
361
362 unregisterHooks(processingData->hookListList,
08365995 363 processingData->traceSetContext);
70407e86
BP
364}
365
366
367/*
368 * Lttv hook function that will be called for network events
369 *
370 * Args:
371 * hookData: LttvTraceHook* for the type of event that generated the call
372 * callData: LttvTracefileContext* at the moment of the event
373 *
374 * Returns:
375 * FALSE Always returns FALSE, meaning to keep processing hooks for
376 * this event
377 */
378static gboolean processEventLTTVStandard(void* hookData, void* callData)
379{
380 LttvTraceHook* traceHook;
381 LttvTracefileContext* tfc;
382 LttEvent* event;
70407e86 383 LttCycleCount tsc;
76be6fc2
BP
384 LttTime time;
385 WallTime wTime;
70407e86
BP
386 LttTrace* trace;
387 unsigned long traceNum;
388 struct marker_info* info;
389 SyncState* syncState;
390 ProcessingDataLTTVStandard* processingData;
053b4b77 391 gpointer traceNumP;
70407e86
BP
392
393 traceHook= (LttvTraceHook*) hookData;
394 tfc= (LttvTracefileContext*) callData;
9a9ca632 395 trace= tfc->t_context->t;
70407e86
BP
396 syncState= (SyncState*) traceHook->hook_data;
397 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
398 event= ltt_tracefile_get_event(tfc->tf);
70407e86 399 info= marker_get_info_from_id(tfc->tf->mdata, event->event_id);
76be6fc2
BP
400 tsc= ltt_event_cycle_count(event);
401 time= ltt_event_time(event);
402 wTime.seconds= time.tv_sec;
403 wTime.nanosec= time.tv_nsec;
70407e86
BP
404
405 g_assert(g_hash_table_lookup_extended(processingData->traceNumTable,
053b4b77
BP
406 trace, NULL, &traceNumP));
407 traceNum= GPOINTER_TO_INT(traceNumP);
70407e86 408
d5b038ec 409 g_debug("Process event: time: %ld.%09ld trace: %ld (%p) name: %s ",
76be6fc2 410 time.tv_sec, time.tv_nsec, traceNum, trace,
70407e86
BP
411 g_quark_to_string(info->name));
412
fea7219b 413 if (info->name == LTT_EVENT_DEV_XMIT_EXTENDED)
70407e86 414 {
10341d26 415 Event* outE;
70407e86
BP
416
417 if (!ltt_event_get_unsigned(event,
418 lttv_trace_get_hook_field(traceHook, 1)) == ETH_P_IP ||
419 !ltt_event_get_unsigned(event,
420 lttv_trace_get_hook_field(traceHook, 2)) == IPPROTO_TCP)
421 {
422 return FALSE;
423 }
424
f6691532
BP
425 if (!syncState->matchingModule->canMatch[TCP])
426 {
427 return FALSE;
428 }
429
70407e86
BP
430 if (syncState->stats)
431 {
432 processingData->stats->totOutE++;
433 }
434
10341d26 435 outE= malloc(sizeof(Event));
70407e86 436 outE->traceNum= traceNum;
76be6fc2
BP
437 outE->cpuTime= tsc;
438 outE->wallTime= wTime;
10341d26 439 outE->type= TCP;
d4721e1a 440 outE->copy= &copyTCPEvent;
10341d26
BP
441 outE->destroy= &destroyTCPEvent;
442 outE->event.tcpEvent= malloc(sizeof(TCPEvent));
443 outE->event.tcpEvent->direction= OUT;
444 outE->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
445 outE->event.tcpEvent->segmentKey->connectionKey.saddr=
d4721e1a
BP
446 htonl(ltt_event_get_unsigned(event,
447 lttv_trace_get_hook_field(traceHook, 3)));
10341d26 448 outE->event.tcpEvent->segmentKey->connectionKey.daddr=
d4721e1a
BP
449 htonl(ltt_event_get_unsigned(event,
450 lttv_trace_get_hook_field(traceHook, 4)));
10341d26
BP
451 outE->event.tcpEvent->segmentKey->tot_len=
452 ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
453 5));
454 outE->event.tcpEvent->segmentKey->ihl= ltt_event_get_unsigned(event,
70407e86 455 lttv_trace_get_hook_field(traceHook, 6));
10341d26
BP
456 outE->event.tcpEvent->segmentKey->connectionKey.source=
457 ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
458 7));
459 outE->event.tcpEvent->segmentKey->connectionKey.dest=
460 ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
461 8));
462 outE->event.tcpEvent->segmentKey->seq= ltt_event_get_unsigned(event,
70407e86 463 lttv_trace_get_hook_field(traceHook, 9));
10341d26
BP
464 outE->event.tcpEvent->segmentKey->ack_seq=
465 ltt_event_get_unsigned(event, lttv_trace_get_hook_field(traceHook,
466 10));
467 outE->event.tcpEvent->segmentKey->doff= ltt_event_get_unsigned(event,
70407e86 468 lttv_trace_get_hook_field(traceHook, 11));
10341d26 469 outE->event.tcpEvent->segmentKey->ack= ltt_event_get_unsigned(event,
70407e86 470 lttv_trace_get_hook_field(traceHook, 12));
10341d26 471 outE->event.tcpEvent->segmentKey->rst= ltt_event_get_unsigned(event,
70407e86 472 lttv_trace_get_hook_field(traceHook, 13));
10341d26 473 outE->event.tcpEvent->segmentKey->syn= ltt_event_get_unsigned(event,
70407e86 474 lttv_trace_get_hook_field(traceHook, 14));
10341d26 475 outE->event.tcpEvent->segmentKey->fin= ltt_event_get_unsigned(event,
70407e86
BP
476 lttv_trace_get_hook_field(traceHook, 15));
477
10341d26 478 syncState->matchingModule->matchEvent(syncState, outE);
70407e86 479
d5b038ec 480 g_debug("Output event done");
70407e86
BP
481 }
482 else if (info->name == LTT_EVENT_DEV_RECEIVE)
483 {
484 guint32 protocol;
485
486 if (syncState->stats)
487 {
488 processingData->stats->totRecv++;
489 }
490
491 protocol= ltt_event_get_unsigned(event,
492 lttv_trace_get_hook_field(traceHook, 1));
493
494 if (protocol == ETH_P_IP)
495 {
10341d26
BP
496 Event* inE;
497 void* skb;
70407e86
BP
498
499 if (syncState->stats)
500 {
501 processingData->stats->totRecvIp++;
502 }
503
10341d26 504 inE= malloc(sizeof(Event));
70407e86 505 inE->traceNum= traceNum;
76be6fc2
BP
506 inE->cpuTime= tsc;
507 inE->wallTime= wTime;
10341d26 508 inE->event.tcpEvent= NULL;
d4721e1a 509 inE->copy= &copyEvent;
10341d26 510 inE->destroy= &destroyEvent;
70407e86 511
10341d26
BP
512 skb= (void*) (long) ltt_event_get_long_unsigned(event,
513 lttv_trace_get_hook_field(traceHook, 0));
514 g_hash_table_replace(processingData->pendingRecv[traceNum], skb,
515 inE);
70407e86 516
d5b038ec 517 g_debug("Adding inE %p for skb %p to pendingRecv", inE, skb);
70407e86
BP
518 }
519 }
fea7219b 520 else if (info->name == LTT_EVENT_TCPV4_RCV_EXTENDED)
70407e86 521 {
10341d26 522 Event* inE;
70407e86
BP
523 void* skb;
524
525 // Search pendingRecv for an event with the same skb
526 skb= (void*) (long) ltt_event_get_long_unsigned(event,
527 lttv_trace_get_hook_field(traceHook, 0));
528
10341d26 529 inE= (Event*)
70407e86
BP
530 g_hash_table_lookup(processingData->pendingRecv[traceNum], skb);
531 if (inE == NULL)
532 {
533 // This should only happen in case of lost events
f6691532 534 g_warning("No matching pending receive event found");
70407e86
BP
535 }
536 else
537 {
538 if (syncState->stats)
539 {
f6691532 540 processingData->stats->totRecvTCP++;
70407e86
BP
541 }
542
543 // If it's there, remove it and proceed with a receive event
544 g_hash_table_steal(processingData->pendingRecv[traceNum], skb);
545
10341d26
BP
546 inE->type= TCP;
547 inE->event.tcpEvent= malloc(sizeof(TCPEvent));
d4721e1a 548 inE->copy= &copyTCPEvent;
10341d26
BP
549 inE->destroy= &destroyTCPEvent;
550 inE->event.tcpEvent->direction= IN;
551 inE->event.tcpEvent->segmentKey= malloc(sizeof(SegmentKey));
552 inE->event.tcpEvent->segmentKey->connectionKey.saddr=
d4721e1a
BP
553 htonl(ltt_event_get_unsigned(event,
554 lttv_trace_get_hook_field(traceHook, 1)));
10341d26 555 inE->event.tcpEvent->segmentKey->connectionKey.daddr=
d4721e1a
BP
556 htonl(ltt_event_get_unsigned(event,
557 lttv_trace_get_hook_field(traceHook, 2)));
10341d26
BP
558 inE->event.tcpEvent->segmentKey->tot_len=
559 ltt_event_get_unsigned(event,
560 lttv_trace_get_hook_field(traceHook, 3));
561 inE->event.tcpEvent->segmentKey->ihl=
562 ltt_event_get_unsigned(event,
563 lttv_trace_get_hook_field(traceHook, 4));
564 inE->event.tcpEvent->segmentKey->connectionKey.source=
565 ltt_event_get_unsigned(event,
566 lttv_trace_get_hook_field(traceHook, 5));
567 inE->event.tcpEvent->segmentKey->connectionKey.dest=
568 ltt_event_get_unsigned(event,
569 lttv_trace_get_hook_field(traceHook, 6));
570 inE->event.tcpEvent->segmentKey->seq=
571 ltt_event_get_unsigned(event,
572 lttv_trace_get_hook_field(traceHook, 7));
573 inE->event.tcpEvent->segmentKey->ack_seq=
574 ltt_event_get_unsigned(event,
575 lttv_trace_get_hook_field(traceHook, 8));
576 inE->event.tcpEvent->segmentKey->doff=
577 ltt_event_get_unsigned(event,
578 lttv_trace_get_hook_field(traceHook, 9));
579 inE->event.tcpEvent->segmentKey->ack=
580 ltt_event_get_unsigned(event,
581 lttv_trace_get_hook_field(traceHook, 10));
582 inE->event.tcpEvent->segmentKey->rst=
583 ltt_event_get_unsigned(event,
584 lttv_trace_get_hook_field(traceHook, 11));
585 inE->event.tcpEvent->segmentKey->syn=
586 ltt_event_get_unsigned(event,
587 lttv_trace_get_hook_field(traceHook, 12));
588 inE->event.tcpEvent->segmentKey->fin=
589 ltt_event_get_unsigned(event,
590 lttv_trace_get_hook_field(traceHook, 13));
591
592 syncState->matchingModule->matchEvent(syncState, inE);
70407e86 593
d5b038ec 594 g_debug("TCP input event %p for skb %p done", inE, skb);
70407e86
BP
595 }
596 }
f6691532 597 else if (info->name == LTT_EVENT_UDPV4_RCV_EXTENDED)
70407e86 598 {
f6691532
BP
599 Event* inE;
600 void* skb;
70407e86 601
f6691532
BP
602 // Search pendingRecv for an event with the same skb
603 skb= (void*) (long) ltt_event_get_long_unsigned(event,
604 lttv_trace_get_hook_field(traceHook, 0));
70407e86 605
f6691532
BP
606 inE= (Event*)
607 g_hash_table_lookup(processingData->pendingRecv[traceNum], skb);
608 if (inE == NULL)
609 {
610 // This should only happen in case of lost events
611 g_warning("No matching pending receive event found");
612 }
613 else
614 {
615 guint64 dataStart;
70407e86 616
f6691532
BP
617 if (syncState->stats)
618 {
619 processingData->stats->totRecvUDP++;
620 }
621
622 // If it's there, remove it and proceed with a receive event
623 g_hash_table_steal(processingData->pendingRecv[traceNum], skb);
624
625 inE->type= UDP;
626 inE->event.udpEvent= malloc(sizeof(UDPEvent));
d4721e1a 627 inE->copy= &copyUDPEvent;
f6691532
BP
628 inE->destroy= &destroyUDPEvent;
629 inE->event.udpEvent->direction= IN;
630 inE->event.udpEvent->datagramKey= malloc(sizeof(DatagramKey));
631 inE->event.udpEvent->datagramKey->saddr=
d4721e1a
BP
632 htonl(ltt_event_get_unsigned(event,
633 lttv_trace_get_hook_field(traceHook, 1)));
f6691532 634 inE->event.udpEvent->datagramKey->daddr=
d4721e1a
BP
635 htonl(ltt_event_get_unsigned(event,
636 lttv_trace_get_hook_field(traceHook, 2)));
f6691532
BP
637 inE->event.udpEvent->unicast= ltt_event_get_unsigned(event,
638 lttv_trace_get_hook_field(traceHook, 3)) == 0 ? false : true;
639 inE->event.udpEvent->datagramKey->ulen=
640 ltt_event_get_unsigned(event,
641 lttv_trace_get_hook_field(traceHook, 4));
642 inE->event.udpEvent->datagramKey->source=
643 ltt_event_get_unsigned(event,
644 lttv_trace_get_hook_field(traceHook, 5));
645 inE->event.udpEvent->datagramKey->dest=
646 ltt_event_get_unsigned(event,
647 lttv_trace_get_hook_field(traceHook, 6));
648 dataStart= ltt_event_get_long_unsigned(event,
649 lttv_trace_get_hook_field(traceHook, 7));
650 g_assert_cmpuint(sizeof(inE->event.udpEvent->datagramKey->dataKey),
651 ==, sizeof(guint64));
652 if (inE->event.udpEvent->datagramKey->ulen - 8 >=
653 sizeof(inE->event.udpEvent->datagramKey->dataKey))
654 {
655 memcpy(inE->event.udpEvent->datagramKey->dataKey, &dataStart,
656 sizeof(inE->event.udpEvent->datagramKey->dataKey));
657 }
658 else
659 {
660 memset(inE->event.udpEvent->datagramKey->dataKey, 0,
661 sizeof(inE->event.udpEvent->datagramKey->dataKey));
662 memcpy(inE->event.udpEvent->datagramKey->dataKey, &dataStart,
663 inE->event.udpEvent->datagramKey->ulen - 8);
664 }
665
666 syncState->matchingModule->matchEvent(syncState, inE);
667
d5b038ec 668 g_debug("UDP input event %p for skb %p done", inE, skb);
f6691532 669 }
70407e86
BP
670 }
671 else
672 {
673 g_assert_not_reached();
674 }
675
676 return FALSE;
677}
08365995
BP
678
679
66eaf2eb
BP
680/*
681 * Write the processing-specific variables in the gnuplot script.
682 *
683 * Args:
684 * syncState: container for synchronization data
685 * i: trace number
686 */
687static void writeProcessingGraphVariablesLTTVStandard(SyncState* const
688 syncState, const unsigned int i)
689{
690 ProcessingDataLTTVStandard* processingData= syncState->processingData;
691 ProcessingGraphsLTTVStandard* traceI= &processingData->graphs[i];
692
693 fprintf(syncState->graphsStream, "clock_freq_%u= %.3f\n", i, (double)
694 traceI->startFreq / traceI->freqScale);
695}
696
697
08365995 698/*
d6ee5003 699 * Write the processing-specific options in the gnuplot script.
08365995
BP
700 *
701 * Args:
08365995
BP
702 * syncState: container for synchronization data
703 * i: first trace number
704 * j: second trace number, garanteed to be larger than i
705 */
467066ee 706static void writeProcessingTraceTraceOptionsLTTVStandard(SyncState* const
8d7d16dd 707 syncState, const unsigned int i, const unsigned int j)
08365995 708{
8d7d16dd 709 fprintf(syncState->graphsStream,
d6ee5003
BP
710 "set key inside right bottom\n"
711 "set xlabel \"Clock %1$u\"\n"
712 "set xtics nomirror\n"
66eaf2eb 713 "set ylabel \"Clock %2$u\"\n"
d6ee5003 714 "set ytics nomirror\n"
08365995 715 "set x2label \"Clock %1$d (s)\"\n"
66eaf2eb 716 "set x2range [GPVAL_X_MIN / clock_freq_%1$u : GPVAL_X_MAX / clock_freq_%1$u]\n"
08365995 717 "set x2tics\n"
66eaf2eb
BP
718 "set y2label \"Clock %2$d (s)\"\n"
719 "set y2range [GPVAL_Y_MIN / clock_freq_%2$u : GPVAL_Y_MAX / clock_freq_%2$u]\n"
720 "set y2tics\n", i, j);
08365995 721}
467066ee
BP
722
723
724/*
725 * Write the processing-specific options in the gnuplot script.
726 *
727 * Args:
728 * syncState: container for synchronization data
729 * i: first trace number
730 * j: second trace number, garanteed to be larger than i
731 */
732static void writeProcessingTraceTimeOptionsLTTVStandard(SyncState* const
733 syncState, const unsigned int i, const unsigned int j)
734{
467066ee
BP
735 fprintf(syncState->graphsStream,
736 "set key inside right bottom\n"
737 "set xlabel \"Clock %1$u\"\n"
738 "set xtics nomirror\n"
739 "set ylabel \"time (s)\"\n"
740 "set ytics nomirror\n"
741 "set x2label \"Clock %1$d (s)\"\n"
66eaf2eb
BP
742 "set x2range [GPVAL_X_MIN / clock_freq_%1$u : GPVAL_X_MAX / clock_freq_%1$u]\n"
743 "set x2tics\n", i);
467066ee 744}
This page took 0.056146 seconds and 4 git commands to generate.