cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / trace-ir / utils.h
CommitLineData
726106d3 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
726106d3 3 *
0235b0db 4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
726106d3
PP
5 */
6
0235b0db
MJ
7#ifndef BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
8#define BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
9
3fadfbc0 10#include <babeltrace2/trace-ir/field-class.h>
c4f23e30 11#include <stdbool.h>
726106d3
PP
12#include <stdint.h>
13
578e048b
MJ
14#include "clock-class.h"
15
3dca2276
PP
16struct search_query {
17 gpointer value;
18 int found;
19};
20
44c440bc
PP
21static inline
22uint64_t bt_util_ns_from_value(uint64_t frequency, uint64_t value_cycles)
23{
24 uint64_t ns;
25
26 if (frequency == UINT64_C(1000000000)) {
27 ns = value_cycles;
28 } else {
29 double dblres = ((1e9 * (double) value_cycles) / (double) frequency);
30
31 if (dblres >= (double) UINT64_MAX) {
32 /* Overflows uint64_t */
33 ns = UINT64_C(-1);
34 } else {
35 ns = (uint64_t) dblres;
36 }
37 }
38
39 return ns;
40}
41
42static inline
0f2d58c9
PP
43bool bt_util_get_base_offset_ns(int64_t offset_seconds, uint64_t offset_cycles,
44 uint64_t frequency, int64_t *base_offset_ns)
44c440bc 45{
0f2d58c9
PP
46 bool overflows = false;
47 uint64_t offset_cycles_ns;
44c440bc 48
98b15851 49 BT_ASSERT_DBG(base_offset_ns);
0f2d58c9
PP
50
51 /* Initialize nanosecond timestamp to clock's offset in seconds */
52 if (offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
53 offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
54 /*
55 * Overflow: offset in seconds converted to nanoseconds
56 * is outside the int64_t range. We also subtract 1 here
57 * to leave "space" for the offset in cycles converted
58 * to nanoseconds (which is always less than 1 second by
59 * contract).
60 */
61 overflows = true;
44c440bc
PP
62 goto end;
63 }
64
0f2d58c9
PP
65 /* Offset (seconds) to nanoseconds */
66 *base_offset_ns = offset_seconds * INT64_C(1000000000);
67
68 /* Add offset in cycles */
98b15851 69 BT_ASSERT_DBG(offset_cycles < frequency);
0f2d58c9
PP
70 offset_cycles_ns = bt_util_ns_from_value(frequency,
71 offset_cycles);
98b15851 72 BT_ASSERT_DBG(offset_cycles_ns < 1000000000);
0f2d58c9
PP
73 *base_offset_ns += (int64_t) offset_cycles_ns;
74
75end:
76 return overflows;
77}
78
79static inline
80int bt_util_ns_from_origin_inline(int64_t base_offset_ns,
0f2d58c9
PP
81 uint64_t frequency, uint64_t value, int64_t *ns_from_origin)
82{
83 int ret = 0;
84 uint64_t value_ns_unsigned;
85 int64_t value_ns_signed;
86
44c440bc 87 /* Initialize to clock class's base offset */
0f2d58c9 88 *ns_from_origin = base_offset_ns;
44c440bc
PP
89
90 /* Add given value in cycles */
0f2d58c9 91 value_ns_unsigned = bt_util_ns_from_value(frequency, value);
44c440bc
PP
92 if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
93 /*
94 * FIXME: `value_ns_unsigned` could be greater than
95 * `INT64_MAX` in fact: in this case, we need to
96 * subtract `INT64_MAX` from `value_ns_unsigned`, make
97 * sure that the difference is less than `INT64_MAX`,
98 * and try to add them one after the other to
99 * `*ns_from_origin`.
100 */
101 ret = -1;
102 goto end;
103 }
104
105 value_ns_signed = (int64_t) value_ns_unsigned;
98b15851 106 BT_ASSERT_DBG(value_ns_signed >= 0);
44c440bc
PP
107
108 if (*ns_from_origin <= 0) {
109 goto add_value;
110 }
111
112 if (value_ns_signed > INT64_MAX - *ns_from_origin) {
113 ret = -1;
114 goto end;
115 }
116
117add_value:
118 *ns_from_origin += value_ns_signed;
119
120end:
121 return ret;
122}
123
0f2d58c9
PP
124static inline
125int bt_util_ns_from_origin_clock_class(const struct bt_clock_class *clock_class,
126 uint64_t value, int64_t *ns_from_origin)
127{
128 int ret = 0;
129
130 if (clock_class->base_offset.overflows) {
131 ret = -1;
132 goto end;
133 }
134
135 ret = bt_util_ns_from_origin_inline(clock_class->base_offset.value_ns,
0f2d58c9
PP
136 clock_class->frequency, value, ns_from_origin);
137
138end:
139 return ret;
140}
141
44c440bc
PP
142static inline
143bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
144{
145 int64_t min_value = UINT64_C(-1) << (size - 1);
146 int64_t max_value = (UINT64_C(1) << (size - 1)) - 1;
147 return value >= min_value && value <= max_value;
148}
149
150static inline
151bool bt_util_value_is_in_range_unsigned(unsigned int size, uint64_t value)
152{
153 uint64_t max_value = (size == 64) ? UINT64_MAX :
154 (UINT64_C(1) << size) - 1;
155 return value <= max_value;
156}
726106d3 157
56e18c4c 158#endif /* BABELTRACE_TRACE_IR_UTILS_INTERNAL_H */
This page took 0.097309 seconds and 5 git commands to generate.