+++ /dev/null
-/*
- * Copyright (C) 2010 Pierre-Marc Fournier
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-#include "ust-clock.hpp"
-
-#include <common/time.hpp>
-#include <common/exception.hpp>
-
-#define CLOCK_OFFSET_SAMPLE_COUNT 10
-
-namespace {
-struct offset_sample {
- /* correlation offset */
- lttng::ust::clock_attributes_sample::scycles_t offset;
- /* lower is better */
- lttng::ust::clock_attributes_sample::cycles_t measure_delta;
-};
-
-lttng::ust::clock_attributes_sample::cycles_t sample_clock_read64()
-{
- lttng_ust_clock_read64_function read64_cb;
-
- if (lttng_ust_trace_clock_get_read64_cb(&read64_cb)) {
- LTTNG_THROW_ERROR("Failed to get clock sample callback");
- }
-
- return read64_cb();
-}
-
-lttng::ust::clock_attributes_sample::cycles_t sample_clock_frequency()
-{
- lttng_ust_clock_freq_function get_freq_cb;
-
- if (lttng_ust_trace_clock_get_freq_cb(&get_freq_cb)) {
- LTTNG_THROW_ERROR("Failed to get clock frequency callback");
- }
-
- return get_freq_cb();
-}
-
-nonstd::optional<lttng_uuid> sample_clock_uuid()
-{
- lttng_ust_clock_uuid_function get_uuid_cb;
-
- if (lttng_ust_trace_clock_get_uuid_cb(&get_uuid_cb)) {
- return nonstd::nullopt;
- }
-
- char uuid_str[LTTNG_UUID_STR_LEN];
- if (get_uuid_cb(uuid_str)) {
- return nonstd::nullopt;
- }
-
- lttng_uuid uuid;
- if (lttng_uuid_from_str(uuid_str, uuid)) {
- LTTNG_THROW_ERROR("Failed to parse UUID from string");
- }
-
- return nonstd::optional<lttng_uuid>{uuid};
-}
-
-const char *sample_clock_name()
-{
- lttng_ust_clock_name_function get_name_cb;
-
- if (lttng_ust_trace_clock_get_name_cb(&get_name_cb)) {
- LTTNG_THROW_ERROR("Failed to get clock name callback");
- }
-
- const auto name = get_name_cb();
- if (!name) {
- LTTNG_THROW_ERROR("Invalid clock name returned by LTTng-UST `lttng_ust_clock_name_function`");
- }
-
- return name;
-}
-
-const char *sample_clock_description()
-{
- lttng_ust_clock_description_function get_description_cb;
-
- if (lttng_ust_trace_clock_get_description_cb(&get_description_cb)) {
- LTTNG_THROW_ERROR("Failed to get clock description callback");
- }
-
- const auto description = get_description_cb();
- if (!description) {
- LTTNG_THROW_ERROR("Invalid clock description returned by LTTng-UST `lttng_ust_clock_description_function`");
- }
-
- return description;
-}
-
-/*
- * The offset between monotonic and realtime clock can be negative if
- * the system sets the REALTIME clock to 0 after boot.
- */
-void measure_single_clock_offset(struct offset_sample *sample)
-{
- lttng::ust::clock_attributes_sample::cycles_t monotonic_avg, monotonic[2], measure_delta,
- realtime;
- const auto tcf = sample_clock_frequency();
- struct timespec rts = { 0, 0 };
-
- monotonic[0] = sample_clock_read64();
- if (lttng_clock_gettime(CLOCK_REALTIME, &rts)) {
- LTTNG_THROW_POSIX("Failed to sample time from clock", errno);
- }
-
- monotonic[1] = sample_clock_read64();
- measure_delta = monotonic[1] - monotonic[0];
- if (measure_delta > sample->measure_delta) {
- /*
- * Discard value if it took longer to read than the best
- * sample so far.
- */
- return;
- }
-
- monotonic_avg = (monotonic[0] + monotonic[1]) >> 1;
- realtime = (lttng::ust::clock_attributes_sample::cycles_t) rts.tv_sec * tcf;
- if (tcf == NSEC_PER_SEC) {
- realtime += rts.tv_nsec;
- } else {
- realtime += (lttng::ust::clock_attributes_sample::cycles_t) rts.tv_nsec * tcf /
- NSEC_PER_SEC;
- }
-
- sample->offset = (lttng::ust::clock_attributes_sample::scycles_t) realtime - monotonic_avg;
- sample->measure_delta = measure_delta;
-}
-
-/*
- * Approximation of NTP time of day to clock monotonic correlation,
- * taken at start of trace. Keep the measurement that took the less time
- * to complete, thus removing imprecision caused by preemption.
- * May return a negative offset.
- */
-lttng::ust::clock_attributes_sample::scycles_t measure_clock_offset(void)
-{
- struct offset_sample offset_best_sample = {
- .offset = 0,
- .measure_delta = UINT64_MAX,
- };
-
- for (auto i = 0; i < CLOCK_OFFSET_SAMPLE_COUNT; i++) {
- measure_single_clock_offset(&offset_best_sample);
- }
-
- return offset_best_sample.offset;
-}
-}
-
-lttng::ust::clock_attributes_sample::clock_attributes_sample() :
- _name{sample_clock_name()},
- _description{sample_clock_description()},
- _uuid{sample_clock_uuid()},
- _offset{measure_clock_offset()},
- _frequency{sample_clock_frequency()}
-{
-}