1 #ifndef BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
2 #define BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
5 * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 #include <babeltrace/babeltrace-internal.h>
27 #include <babeltrace/object-internal.h>
28 #include <babeltrace/ctf-ir/clock-class-internal.h>
32 struct bt_clock_class
;
34 struct bt_clock_value
{
35 struct bt_object base
;
36 struct bt_clock_class
*clock_class
;
38 bool ns_from_epoch_overflows
;
39 int64_t ns_from_epoch
;
45 void bt_clock_value_set(struct bt_clock_value
*clock_value
)
47 BT_ASSERT(clock_value
);
48 clock_value
->is_set
= true;
52 void bt_clock_value_reset(struct bt_clock_value
*clock_value
)
54 BT_ASSERT(clock_value
);
55 clock_value
->is_set
= false;
60 void _bt_clock_value_set_is_frozen(struct bt_clock_value
*clock_value
,
63 BT_ASSERT(clock_value
);
64 clock_value
->frozen
= is_frozen
;
68 uint64_t ns_from_value(uint64_t frequency
, uint64_t value
)
72 if (frequency
== UINT64_C(1000000000)) {
75 double dblres
= ((1e9
* (double) value
) / (double) frequency
);
77 if (dblres
>= (double) UINT64_MAX
) {
78 /* Overflows uint64_t */
81 ns
= (uint64_t) dblres
;
89 int ns_from_epoch(struct bt_clock_class
*clock_class
, uint64_t value
,
90 int64_t *ns_from_epoch
, bool *overflows
)
100 /* Initialize nanosecond timestamp to clock's offset in seconds */
101 if (clock_class
->offset_s
<= (INT64_MIN
/ INT64_C(1000000000)) ||
102 clock_class
->offset_s
>= (INT64_MAX
/ INT64_C(1000000000))) {
104 * Overflow: offset in seconds converted to nanoseconds
105 * is outside the int64_t range.
111 *ns_from_epoch
= clock_class
->offset_s
* INT64_C(1000000000);
113 /* Add offset in cycles */
114 if (clock_class
->offset
< 0) {
115 cycles
= (uint64_t) -clock_class
->offset
;
117 cycles
= (uint64_t) clock_class
->offset
;
120 u_ns
= ns_from_value(clock_class
->frequency
, cycles
);
122 if (u_ns
== UINT64_C(-1) || u_ns
>= INT64_MAX
) {
124 * Overflow: offset in cycles converted to nanoseconds
125 * is outside the int64_t range.
131 s_ns
= (int64_t) u_ns
;
132 BT_ASSERT(s_ns
>= 0);
134 if (clock_class
->offset
< 0) {
135 if (*ns_from_epoch
>= 0) {
137 * Offset in cycles is negative so it must also
138 * be negative once converted to nanoseconds.
144 diff
= *ns_from_epoch
- INT64_MIN
;
148 * Overflow: current timestamp in nanoseconds
149 * plus the offset in cycles converted to
150 * nanoseconds is outside the int64_t range.
157 * Offset in cycles is negative so it must also be
158 * negative once converted to nanoseconds.
162 if (*ns_from_epoch
<= 0) {
166 diff
= INT64_MAX
- *ns_from_epoch
;
170 * Overflow: current timestamp in nanoseconds
171 * plus the offset in cycles converted to
172 * nanoseconds is outside the int64_t range.
180 *ns_from_epoch
+= s_ns
;
182 /* Add clock value (cycles) */
183 u_ns
= ns_from_value(clock_class
->frequency
, value
);
185 if (u_ns
== -1ULL || u_ns
>= INT64_MAX
) {
187 * Overflow: value converted to nanoseconds is outside
194 s_ns
= (int64_t) u_ns
;
195 BT_ASSERT(s_ns
>= 0);
197 /* Clock value (cycles) is always positive */
198 if (*ns_from_epoch
<= 0) {
202 diff
= INT64_MAX
- *ns_from_epoch
;
206 * Overflow: current timestamp in nanoseconds plus the
207 * clock value converted to nanoseconds is outside the
215 *ns_from_epoch
+= s_ns
;
227 void set_ns_from_epoch(struct bt_clock_value
*clock_value
)
229 (void) ns_from_epoch(clock_value
->clock_class
,
230 clock_value
->value
, &clock_value
->ns_from_epoch
,
231 &clock_value
->ns_from_epoch_overflows
);
235 void bt_clock_value_set_raw_value(struct bt_clock_value
*clock_value
,
238 BT_ASSERT(clock_value
);
240 clock_value
->value
= cycles
;
241 set_ns_from_epoch(clock_value
);
242 bt_clock_value_set(clock_value
);
246 int bt_clock_value_set_value_inline(struct bt_clock_value
*clock_value
,
249 #ifdef BT_ASSERT_PRE_NON_NULL
250 BT_ASSERT_PRE_NON_NULL(clock_value
, "Clock value");
253 #ifdef BT_ASSERT_PRE_HOT
254 BT_ASSERT_PRE_HOT(clock_value
, "Clock value", ": %!+k", clock_value
);
257 bt_clock_value_set_raw_value(clock_value
, raw_value
);
262 # define bt_clock_value_set_is_frozen _bt_clock_value_set_is_frozen
264 # define bt_clock_value_set_is_frozen(_x, _f)
265 #endif /* BT_DEV_MODE */
268 struct bt_clock_value
*bt_clock_value_create(
269 struct bt_clock_class
*clock_class
);
272 void bt_clock_value_recycle(struct bt_clock_value
*clock_value
);
275 void bt_clock_value_set_raw_value(struct bt_clock_value
*clock_value
,
278 #endif /* BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H */
This page took 0.035706 seconds and 4 git commands to generate.