#define BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
/*
- * Babeltrace - Internal Trace IR utilities
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
*/
#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-class.h>
#include <babeltrace/trace-ir/clock-class-internal.h>
#include <stdint.h>
}
static inline
-int bt_util_ns_from_origin(struct bt_clock_class *clock_class, uint64_t value,
- int64_t *ns_from_origin)
+bool bt_util_get_base_offset_ns(int64_t offset_seconds, uint64_t offset_cycles,
+ uint64_t frequency, int64_t *base_offset_ns)
{
- int ret = 0;
- uint64_t value_ns_unsigned;
- int64_t value_ns_signed;
+ bool overflows = false;
+ uint64_t offset_cycles_ns;
- if (clock_class->base_offset.overflows) {
- ret = -1;
+ BT_ASSERT(base_offset_ns);
+
+ /* Initialize nanosecond timestamp to clock's offset in seconds */
+ if (offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
+ offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
+ /*
+ * Overflow: offset in seconds converted to nanoseconds
+ * is outside the int64_t range. We also subtract 1 here
+ * to leave "space" for the offset in cycles converted
+ * to nanoseconds (which is always less than 1 second by
+ * contract).
+ */
+ overflows = true;
goto end;
}
+ /* Offset (seconds) to nanoseconds */
+ *base_offset_ns = offset_seconds * INT64_C(1000000000);
+
+ /* Add offset in cycles */
+ BT_ASSERT(offset_cycles < frequency);
+ offset_cycles_ns = bt_util_ns_from_value(frequency,
+ offset_cycles);
+ BT_ASSERT(offset_cycles_ns < 1000000000);
+ *base_offset_ns += (int64_t) offset_cycles_ns;
+
+end:
+ return overflows;
+}
+
+static inline
+int bt_util_ns_from_origin_inline(int64_t base_offset_ns,
+ int64_t offset_seconds, uint64_t offset_cycles,
+ uint64_t frequency, uint64_t value, int64_t *ns_from_origin)
+{
+ int ret = 0;
+ uint64_t value_ns_unsigned;
+ int64_t value_ns_signed;
+
/* Initialize to clock class's base offset */
- *ns_from_origin = clock_class->base_offset.value_ns;
+ *ns_from_origin = base_offset_ns;
/* Add given value in cycles */
- value_ns_unsigned = bt_util_ns_from_value(clock_class->frequency, value);
+ value_ns_unsigned = bt_util_ns_from_value(frequency, value);
if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
/*
* FIXME: `value_ns_unsigned` could be greater than
return ret;
}
+static inline
+int bt_util_ns_from_origin_clock_class(const struct bt_clock_class *clock_class,
+ uint64_t value, int64_t *ns_from_origin)
+{
+ int ret = 0;
+
+ if (clock_class->base_offset.overflows) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_util_ns_from_origin_inline(clock_class->base_offset.value_ns,
+ clock_class->offset_seconds, clock_class->offset_cycles,
+ clock_class->frequency, value, ns_from_origin);
+
+end:
+ return ret;
+}
+
static inline
bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
{