ctf: Ignore invalid clock description elements
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / metadata / tsdl / ClockParser.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl;
11
12 import java.util.List;
13
14 import org.antlr.runtime.tree.CommonTree;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.tracecompass.ctf.core.event.CTFClock;
17 import org.eclipse.tracecompass.ctf.parser.CTFParser;
18 import org.eclipse.tracecompass.internal.ctf.core.Activator;
19 import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ICommonTreeParser;
20 import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException;
21
22 /**
23 * Clock metadata allows to describe the clock topology of the system, as well
24 * as to detail each clock parameter. In absence of clock description, it is
25 * assumed that all fields named timestamp use the same clock source, which
26 * increments once per nanosecond.
27 * <p>
28 * Describing a clock and how it is used by streams is threefold: first, the
29 * clock and clock topology should be described in a clock description block,
30 * e.g.:
31 *
32 * <pre>
33 clock {
34 name = cycle_counter_sync;
35 uuid = "62189bee-96dc-11e0-91a8-cfa3d89f3923";
36 description = "Cycle counter synchronized across CPUs";
37 freq = 1000000000; // frequency, in Hz
38 // precision in seconds is: 1000 * (1/freq)
39 precision = 1000;
40
41 // clock value offset from Epoch is:
42 // offset_s + (offset * (1/freq))
43
44 offset_s = 1326476837;
45 offset = 897235420;
46 absolute = FALSE;
47 };
48 * </pre>
49 *
50 * The mandatory name field specifies the name of the clock identifier, which
51 * can later be used as a reference. The optional field uuid is the unique
52 * identifier of the clock. It can be used to correlate different traces that
53 * use the same clock. An optional textual description string can be added with
54 * the description field. The freq field is the initial frequency of the clock,
55 * in Hz. If the freq field is not present, the frequency is assumed to be
56 * 1000000000 (providing clock increment of 1 ns). The optional precision field
57 * details the uncertainty on the clock measurements, in (1/freq) units. The
58 * offset_s and offset fields indicate the offset from POSIX.1 Epoch, 1970-01-01
59 * 00:00:00 +0000 (UTC), to the zero of value of the clock. The offset_s field
60 * is in seconds. The offset field is in (1/freq) units. If any of the offset_s
61 * or offset field is not present, it is assigned the 0 value. The field
62 * absolute is TRUE if the clock is a global reference across different clock
63 * UUID (e.g. NTP time). Otherwise, absolute is FALSE, and the clock can be
64 * considered as synchronized only with other clocks that have the same UUID.
65 * <p>
66 * Secondly, a reference to this clock should be added within an integer type:
67 *
68 * <pre>
69 typealias integer {
70 size = 64; align = 1; signed = false;
71 map = clock.cycle_counter_sync.value;
72 } := uint64_ccnt_t;
73 * </pre>
74 *
75 * Thirdly, stream declarations can reference the clock they use as a timestamp
76 * source:
77 *
78 * <pre>
79 struct packet_context {
80 uint64_ccnt_t ccnt_begin;
81 uint64_ccnt_t ccnt_end;
82 // ...
83 };
84
85 stream {
86 // ...
87 event.header := struct {
88 uint64_ccnt_t timestamp;
89 // ...
90 };
91 packet.context := struct packet_context;
92 };
93 * </pre>
94 *
95 * For a N-bit integer type referring to a clock, if the integer overflows
96 * compared to the N low order bits of the clock prior value found in the same
97 * stream, then it is assumed that one, and only one, overflow occurred. It is
98 * therefore important that events encoding time on a small number of bits
99 * happen frequently enough to detect when more than one N-bit overflow occurs.
100 * <p>
101 * In a packet context, clock field names ending with _begin and _end have a
102 * special meaning: this refers to the timestamps at, respectively, the
103 * beginning and the end of each packet.
104 *
105 * @author Matthew Khouzam - Initial API and implementation
106 * @author Efficios (documentation)
107 *
108 */
109 public final class ClockParser implements ICommonTreeParser {
110
111 /**
112 * Instance
113 */
114 public static final ClockParser INSTANCE = new ClockParser();
115
116 private ClockParser() {
117 }
118
119 @Override
120 public CTFClock parse(CommonTree clock, ICommonTreeParserParameter unused) throws ParseException {
121 List<CommonTree> children = clock.getChildren();
122 CTFClock ctfClock = new CTFClock();
123 for (CommonTree child : children) {
124 final String key = child.getChild(0).getChild(0).getChild(0).getText();
125 final CommonTree value = (CommonTree) child.getChild(1).getChild(0).getChild(0);
126 final int type = value.getType();
127 final String text = value.getText();
128 switch (type) {
129 case CTFParser.INTEGER:
130 case CTFParser.DECIMAL_LITERAL:
131 /*
132 * Not a pretty hack, this is to make sure that there is no
133 * number overflow due to 63 bit integers. The offset should
134 * only really be an issue in the year 2262. the tracer in C/ASM
135 * can write an offset in an unsigned 64 bit long. In java, the
136 * last bit, being set to 1 will be read as a negative number,
137 * but since it is too big a positive it will throw an
138 * exception. this will happen in 2^63 ns from 1970. Therefore
139 * 293 years from 1970
140 */
141 Long numValue;
142 try {
143 numValue = Long.parseLong(text);
144 } catch (NumberFormatException e) {
145 Activator.log(IStatus.WARNING, "Number conversion issue with " + text + ". Assigning " + key + " = 0."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
146 numValue = Long.valueOf(0L);
147 }
148 ctfClock.addAttribute(key, numValue);
149 break;
150 default:
151 ctfClock.addAttribute(key, text);
152 }
153
154 }
155 return ctfClock;
156
157 }
158
159 }
This page took 0.035616 seconds and 5 git commands to generate.