2020-03-02 18:16:15 +00:00
|
|
|
// Copyright 2019-2020, Collabora, Ltd.
|
2019-03-18 05:52:32 +00:00
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Implementation of a steady, convertible clock.
|
|
|
|
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
2019-04-06 11:28:56 +00:00
|
|
|
* @ingroup aux_util
|
2019-03-18 05:52:32 +00:00
|
|
|
*/
|
|
|
|
|
2020-03-05 11:25:44 +00:00
|
|
|
#include "xrt/xrt_config_os.h"
|
2020-03-02 18:16:15 +00:00
|
|
|
#include "xrt/xrt_compiler.h"
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
#include "os/os_time.h"
|
|
|
|
|
|
|
|
#include "u_time.h"
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
#include <new>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
2020-03-02 18:16:15 +00:00
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Structs.
|
|
|
|
*
|
|
|
|
*/
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
struct time_state
|
|
|
|
{
|
2020-05-26 19:09:56 +00:00
|
|
|
// Hardcoded to one second offset.
|
|
|
|
timepoint_ns offset = 1000 * 1000 * 1000;
|
2019-03-18 05:52:32 +00:00
|
|
|
};
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* 'Exported' functions.
|
|
|
|
*
|
|
|
|
*/
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" struct time_state *
|
2019-03-18 05:52:32 +00:00
|
|
|
time_state_create()
|
|
|
|
{
|
2019-09-29 10:43:23 +00:00
|
|
|
time_state *state = new (std::nothrow) time_state;
|
2019-03-18 05:52:32 +00:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" void
|
|
|
|
time_state_destroy(struct time_state **state_ptr)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
2019-11-15 20:30:01 +00:00
|
|
|
struct time_state *state = *state_ptr;
|
|
|
|
|
|
|
|
if (state == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
delete state;
|
2019-11-15 20:30:01 +00:00
|
|
|
*state_ptr = NULL;
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" timepoint_ns
|
2019-09-29 10:43:23 +00:00
|
|
|
time_state_get_now(struct time_state const *state)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(state != NULL);
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
return time_state_monotonic_to_ts_ns(state, os_monotonic_get_ns());
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" timepoint_ns
|
2019-09-29 10:43:23 +00:00
|
|
|
time_state_get_now_and_update(struct time_state *state)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(state != NULL);
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
return time_state_get_now(state);
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" void
|
2019-09-29 10:43:23 +00:00
|
|
|
time_state_to_timespec(struct time_state const *state,
|
2019-03-18 05:52:32 +00:00
|
|
|
timepoint_ns timestamp,
|
2019-09-29 10:43:23 +00:00
|
|
|
struct timespec *out)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(state != NULL);
|
|
|
|
assert(out != NULL);
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
uint64_t ns = time_state_ts_to_monotonic_ns(state, timestamp);
|
|
|
|
|
|
|
|
out->tv_sec = ns / (1000 * 1000 * 1000);
|
|
|
|
out->tv_nsec = ns % (1000 * 1000 * 1000);
|
|
|
|
}
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2019-11-15 20:28:24 +00:00
|
|
|
extern "C" timepoint_ns
|
2019-09-29 10:43:23 +00:00
|
|
|
time_state_from_timespec(struct time_state const *state,
|
|
|
|
const struct timespec *timespecTime)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(state != NULL);
|
|
|
|
assert(timespecTime != NULL);
|
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
uint64_t ns = 0;
|
|
|
|
ns += timespecTime->tv_nsec;
|
|
|
|
ns += timespecTime->tv_sec * 1000 * 1000 * 1000;
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
return time_state_monotonic_to_ts_ns(state, ns);
|
|
|
|
}
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
extern "C" timepoint_ns
|
|
|
|
time_state_monotonic_to_ts_ns(struct time_state const *state,
|
|
|
|
uint64_t monotonic_ns)
|
|
|
|
{
|
|
|
|
assert(state != NULL);
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
return monotonic_ns + state->offset;
|
2020-02-27 13:46:10 +00:00
|
|
|
}
|
2020-03-02 18:16:15 +00:00
|
|
|
|
2020-05-26 19:09:56 +00:00
|
|
|
extern "C" uint64_t
|
|
|
|
time_state_ts_to_monotonic_ns(struct time_state const *state,
|
|
|
|
timepoint_ns timestamp)
|
2020-03-02 18:16:15 +00:00
|
|
|
{
|
2020-05-26 19:09:56 +00:00
|
|
|
return timestamp - state->offset;
|
2020-03-02 18:16:15 +00:00
|
|
|
}
|