Do not use __attribute__((constructor))
[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 gboolean processEventLTTVStandard(void* hookData, void* callData);
58 static void partialDestroyProcessingLTTVStandard(SyncState* const syncState);
59
60
61 static ProcessingModule processingModuleLTTVStandard = {
62 .name= "LTTV-standard",
63 .initProcessing= &initProcessingLTTVStandard,
64 .destroyProcessing= &destroyProcessingLTTVStandard,
65 .finalizeProcessing= &finalizeProcessingLTTVStandard,
66 .printProcessingStats= &printProcessingStatsLTTVStandard,
67 .graphFunctions= {
68 .writeVariables= &writeProcessingGraphVariablesLTTVStandard,
69 .writeTraceTraceOptions= &writeProcessingTraceTraceOptionsLTTVStandard,
70 .writeTraceTimeOptions= &writeProcessingTraceTimeOptionsLTTVStandard,
71 },
72 };
73
74
75 /*
76 * Processing Module registering function
77 */
78 void registerProcessingLTTVStandard()
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
97 * traceSetContext: LttvTracesetContext*, set of LTTV traces
98 */
99 static void initProcessingLTTVStandard(SyncState* const syncState, ...)
100 {
101 unsigned int i;
102 ProcessingDataLTTVStandard* processingData;
103 va_list ap;
104
105 processingData= malloc(sizeof(ProcessingDataLTTVStandard));
106 syncState->processingData= processingData;
107 va_start(ap, syncState);
108 processingData->traceSetContext= va_arg(ap, LttvTracesetContext*);
109 va_end(ap);
110 syncState->traceNb=
111 lttv_traceset_number(processingData->traceSetContext->ts);
112 processingData->hookListList= g_array_sized_new(FALSE, FALSE,
113 sizeof(GArray*), syncState->traceNb);
114
115 processingData->traceNumTable= g_hash_table_new(&g_direct_hash, NULL);
116 for(i= 0; i < syncState->traceNb; i++)
117 {
118 g_hash_table_insert(processingData->traceNumTable,
119 processingData->traceSetContext->traces[i]->t,
120 GUINT_TO_POINTER(i));
121 }
122
123 processingData->pendingRecv= malloc(sizeof(GHashTable*) *
124 syncState->traceNb);
125 for(i= 0; i < syncState->traceNb; i++)
126 {
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;
138 }
139
140 if (syncState->graphsStream)
141 {
142 processingData->graphs= malloc(syncState->traceNb *
143 sizeof(ProcessingGraphsLTTVStandard));
144
145 for(i= 0; i < syncState->traceNb; i++)
146 {
147 LttTrace* traceI= processingData->traceSetContext->traces[i]->t;
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
158 registerHooks(processingData->hookListList,
159 processingData->traceSetContext, &processEventLTTVStandard, syncState,
160 syncState->matchingModule->canMatch);
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 */
171 static 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
242 g_debug("traceset start %ld.%09ld end %ld.%09ld",
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);
247 }
248
249
250 /*
251 * Print statistics related to processing Must be called after
252 * finalizeProcessing.
253 *
254 * Args:
255 * syncState container for synchronization data.
256 */
257 static void printProcessingStatsLTTVStandard(SyncState* const syncState)
258 {
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);
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 }
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 */
298 static 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
316 if (syncState->graphsStream)
317 {
318 free(processingData->graphs);
319 }
320
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 */
339 static 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
357 g_debug("Cleaning up pendingRecv list");
358 g_hash_table_destroy(processingData->pendingRecv[i]);
359 }
360 free(processingData->pendingRecv);
361
362 unregisterHooks(processingData->hookListList,
363 processingData->traceSetContext);
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 */
378 static gboolean processEventLTTVStandard(void* hookData, void* callData)
379 {
380 LttvTraceHook* traceHook;
381 LttvTracefileContext* tfc;
382 LttEvent* event;
383 LttCycleCount tsc;
384 LttTime time;
385 WallTime wTime;
386 LttTrace* trace;
387 unsigned long traceNum;
388 struct marker_info* info;
389 SyncState* syncState;
390 ProcessingDataLTTVStandard* processingData;
391 gpointer traceNumP;
392
393 traceHook= (LttvTraceHook*) hookData;
394 tfc= (LttvTracefileContext*) callData;
395 trace= tfc->t_context->t;
396 syncState= (SyncState*) traceHook->hook_data;
397 processingData= (ProcessingDataLTTVStandard*) syncState->processingData;
398 event= ltt_tracefile_get_event(tfc->tf);
399 info= marker_get_info_from_id(tfc->tf->mdata, event->event_id);
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;
404
405 g_assert(g_hash_table_lookup_extended(processingData->traceNumTable,
406 trace, NULL, &traceNumP));
407 traceNum= GPOINTER_TO_INT(traceNumP);
408
409 g_debug("Process event: time: %ld.%09ld trace: %ld (%p) name: %s ",
410 time.tv_sec, time.tv_nsec, traceNum, trace,
411 g_quark_to_string(info->name));
412
413 if (info->name == LTT_EVENT_DEV_XMIT_EXTENDED)
414 {
415 Event* outE;
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
425 if (!syncState->matchingModule->canMatch[TCP])
426 {
427 return FALSE;
428 }
429
430 if (syncState->stats)
431 {
432 processingData->stats->totOutE++;
433 }
434
435 outE= malloc(sizeof(Event));
436 outE->traceNum= traceNum;
437 outE->cpuTime= tsc;
438 outE->wallTime= wTime;
439 outE->type= TCP;
440 outE->copy= &copyTCPEvent;
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=
446 htonl(ltt_event_get_unsigned(event,
447 lttv_trace_get_hook_field(traceHook, 3)));
448 outE->event.tcpEvent->segmentKey->connectionKey.daddr=
449 htonl(ltt_event_get_unsigned(event,
450 lttv_trace_get_hook_field(traceHook, 4)));
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,
455 lttv_trace_get_hook_field(traceHook, 6));
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,
463 lttv_trace_get_hook_field(traceHook, 9));
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,
468 lttv_trace_get_hook_field(traceHook, 11));
469 outE->event.tcpEvent->segmentKey->ack= ltt_event_get_unsigned(event,
470 lttv_trace_get_hook_field(traceHook, 12));
471 outE->event.tcpEvent->segmentKey->rst= ltt_event_get_unsigned(event,
472 lttv_trace_get_hook_field(traceHook, 13));
473 outE->event.tcpEvent->segmentKey->syn= ltt_event_get_unsigned(event,
474 lttv_trace_get_hook_field(traceHook, 14));
475 outE->event.tcpEvent->segmentKey->fin= ltt_event_get_unsigned(event,
476 lttv_trace_get_hook_field(traceHook, 15));
477
478 syncState->matchingModule->matchEvent(syncState, outE);
479
480 g_debug("Output event done");
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 {
496 Event* inE;
497 void* skb;
498
499 if (syncState->stats)
500 {
501 processingData->stats->totRecvIp++;
502 }
503
504 inE= malloc(sizeof(Event));
505 inE->traceNum= traceNum;
506 inE->cpuTime= tsc;
507 inE->wallTime= wTime;
508 inE->event.tcpEvent= NULL;
509 inE->copy= &copyEvent;
510 inE->destroy= &destroyEvent;
511
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);
516
517 g_debug("Adding inE %p for skb %p to pendingRecv", inE, skb);
518 }
519 }
520 else if (info->name == LTT_EVENT_TCPV4_RCV_EXTENDED)
521 {
522 Event* inE;
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
529 inE= (Event*)
530 g_hash_table_lookup(processingData->pendingRecv[traceNum], skb);
531 if (inE == NULL)
532 {
533 // This should only happen in case of lost events
534 g_warning("No matching pending receive event found");
535 }
536 else
537 {
538 if (syncState->stats)
539 {
540 processingData->stats->totRecvTCP++;
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
546 inE->type= TCP;
547 inE->event.tcpEvent= malloc(sizeof(TCPEvent));
548 inE->copy= &copyTCPEvent;
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=
553 htonl(ltt_event_get_unsigned(event,
554 lttv_trace_get_hook_field(traceHook, 1)));
555 inE->event.tcpEvent->segmentKey->connectionKey.daddr=
556 htonl(ltt_event_get_unsigned(event,
557 lttv_trace_get_hook_field(traceHook, 2)));
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);
593
594 g_debug("TCP input event %p for skb %p done", inE, skb);
595 }
596 }
597 else if (info->name == LTT_EVENT_UDPV4_RCV_EXTENDED)
598 {
599 Event* inE;
600 void* skb;
601
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));
605
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;
616
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));
627 inE->copy= &copyUDPEvent;
628 inE->destroy= &destroyUDPEvent;
629 inE->event.udpEvent->direction= IN;
630 inE->event.udpEvent->datagramKey= malloc(sizeof(DatagramKey));
631 inE->event.udpEvent->datagramKey->saddr=
632 htonl(ltt_event_get_unsigned(event,
633 lttv_trace_get_hook_field(traceHook, 1)));
634 inE->event.udpEvent->datagramKey->daddr=
635 htonl(ltt_event_get_unsigned(event,
636 lttv_trace_get_hook_field(traceHook, 2)));
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
668 g_debug("UDP input event %p for skb %p done", inE, skb);
669 }
670 }
671 else
672 {
673 g_assert_not_reached();
674 }
675
676 return FALSE;
677 }
678
679
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 */
687 static 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
698 /*
699 * Write the processing-specific options in the gnuplot script.
700 *
701 * Args:
702 * syncState: container for synchronization data
703 * i: first trace number
704 * j: second trace number, garanteed to be larger than i
705 */
706 static void writeProcessingTraceTraceOptionsLTTVStandard(SyncState* const
707 syncState, const unsigned int i, const unsigned int j)
708 {
709 fprintf(syncState->graphsStream,
710 "set key inside right bottom\n"
711 "set xlabel \"Clock %1$u\"\n"
712 "set xtics nomirror\n"
713 "set ylabel \"Clock %2$u\"\n"
714 "set ytics nomirror\n"
715 "set x2label \"Clock %1$d (s)\"\n"
716 "set x2range [GPVAL_X_MIN / clock_freq_%1$u : GPVAL_X_MAX / clock_freq_%1$u]\n"
717 "set x2tics\n"
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);
721 }
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 */
732 static void writeProcessingTraceTimeOptionsLTTVStandard(SyncState* const
733 syncState, const unsigned int i, const unsigned int j)
734 {
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"
742 "set x2range [GPVAL_X_MIN / clock_freq_%1$u : GPVAL_X_MAX / clock_freq_%1$u]\n"
743 "set x2tics\n", i);
744 }
This page took 0.044528 seconds and 4 git commands to generate.