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