1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
;
12 import java
.util
.List
;
14 import org
.antlr
.runtime
.tree
.CommonTree
;
15 import org
.eclipse
.tracecompass
.ctf
.core
.event
.CTFClock
;
16 import org
.eclipse
.tracecompass
.ctf
.parser
.CTFParser
;
17 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.ICommonTreeParser
;
18 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.ParseException
;
21 * Clock metadata allows to describe the clock topology of the system, as well
22 * as to detail each clock parameter. In absence of clock description, it is
23 * assumed that all fields named timestamp use the same clock source, which
24 * increments once per nanosecond.
26 * Describing a clock and how it is used by streams is threefold: first, the
27 * clock and clock topology should be described in a clock description block,
32 name = cycle_counter_sync;
33 uuid = "62189bee-96dc-11e0-91a8-cfa3d89f3923";
34 description = "Cycle counter synchronized across CPUs";
35 freq = 1000000000; // frequency, in Hz
36 // precision in seconds is: 1000 * (1/freq)
39 // clock value offset from Epoch is:
40 // offset_s + (offset * (1/freq))
42 offset_s = 1326476837;
48 * The mandatory name field specifies the name of the clock identifier, which
49 * can later be used as a reference. The optional field uuid is the unique
50 * identifier of the clock. It can be used to correlate different traces that
51 * use the same clock. An optional textual description string can be added with
52 * the description field. The freq field is the initial frequency of the clock,
53 * in Hz. If the freq field is not present, the frequency is assumed to be
54 * 1000000000 (providing clock increment of 1 ns). The optional precision field
55 * details the uncertainty on the clock measurements, in (1/freq) units. The
56 * offset_s and offset fields indicate the offset from POSIX.1 Epoch, 1970-01-01
57 * 00:00:00 +0000 (UTC), to the zero of value of the clock. The offset_s field
58 * is in seconds. The offset field is in (1/freq) units. If any of the offset_s
59 * or offset field is not present, it is assigned the 0 value. The field
60 * absolute is TRUE if the clock is a global reference across different clock
61 * UUID (e.g. NTP time). Otherwise, absolute is FALSE, and the clock can be
62 * considered as synchronized only with other clocks that have the same UUID.
64 * Secondly, a reference to this clock should be added within an integer type:
68 size = 64; align = 1; signed = false;
69 map = clock.cycle_counter_sync.value;
73 * Thirdly, stream declarations can reference the clock they use as a timestamp
77 struct packet_context {
78 uint64_ccnt_t ccnt_begin;
79 uint64_ccnt_t ccnt_end;
85 event.header := struct {
86 uint64_ccnt_t timestamp;
89 packet.context := struct packet_context;
93 * For a N-bit integer type referring to a clock, if the integer overflows
94 * compared to the N low order bits of the clock prior value found in the same
95 * stream, then it is assumed that one, and only one, overflow occurred. It is
96 * therefore important that events encoding time on a small number of bits
97 * happen frequently enough to detect when more than one N-bit overflow occurs.
99 * In a packet context, clock field names ending with _begin and _end have a
100 * special meaning: this refers to the timestamps at, respectively, the
101 * beginning and the end of each packet.
103 * @author Matthew Khouzam - Initial API and implementation
104 * @author Efficios (documentation)
107 public final class ClockParser
implements ICommonTreeParser
{
112 public static final ClockParser INSTANCE
= new ClockParser();
114 private ClockParser() {
118 public CTFClock
parse(CommonTree clock
, ICommonTreeParserParameter unused
) throws ParseException
{
119 List
<CommonTree
> children
= clock
.getChildren();
120 CTFClock ctfClock
= new CTFClock();
121 for (CommonTree child
: children
) {
122 final String key
= child
.getChild(0).getChild(0).getChild(0).getText();
123 final CommonTree value
= (CommonTree
) child
.getChild(1).getChild(0).getChild(0);
124 final int type
= value
.getType();
125 final String text
= value
.getText();
127 case CTFParser
.INTEGER
:
128 case CTFParser
.DECIMAL_LITERAL
:
130 * Not a pretty hack, this is to make sure that there is no
131 * number overflow due to 63 bit integers. The offset should
132 * only really be an issue in the year 2262. the tracer in C/ASM
133 * can write an offset in an unsigned 64 bit long. In java, the
134 * last bit, being set to 1 will be read as a negative number,
135 * but since it is too big a positive it will throw an
136 * exception. this will happen in 2^63 ns from 1970. Therefore
137 * 293 years from 1970
141 numValue
= Long
.parseLong(text
);
142 } catch (NumberFormatException e
) {
143 throw new ParseException("Number conversion issue with " + text
, e
); //$NON-NLS-1$
145 ctfClock
.addAttribute(key
, numValue
);
148 ctfClock
.addAttribute(key
, text
);