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