monado/src/xrt/auxiliary/util/u_time.cpp

145 lines
2.8 KiB
C++
Raw Normal View History

// 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>
* @ingroup aux_util
2019-03-18 05:52:32 +00:00
*/
#include "xrt/xrt_config_os.h"
#include "xrt/xrt_compiler.h"
2019-03-18 05:52:32 +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>
#include <time.h>
/*
*
* Structs.
*
*/
2019-03-18 05:52:32 +00:00
struct time_state
{
timepoint_ns offset;
2019-03-18 05:52:32 +00:00
};
/*
*
* 'Exported' functions.
*
*/
2019-03-18 05:52:32 +00:00
extern "C" struct time_state *
time_state_create(uint64_t offset)
2019-03-18 05:52:32 +00:00
{
time_state *state = new (std::nothrow) time_state;
2022-07-13 17:21:51 +00:00
if (!state) {
return state;
}
state->offset = offset;
2019-03-18 05:52:32 +00:00
return state;
}
extern "C" void
time_state_destroy(struct time_state **state_ptr)
2019-03-18 05:52:32 +00:00
{
struct time_state *state = *state_ptr;
if (state == NULL) {
return;
}
2019-03-18 05:52:32 +00:00
delete state;
*state_ptr = NULL;
2019-03-18 05:52:32 +00:00
}
extern "C" timepoint_ns
time_state_get_now(struct time_state const *state)
2019-03-18 05:52:32 +00:00
{
assert(state != NULL);
return time_state_monotonic_to_ts_ns(state, os_monotonic_get_ns());
2019-03-18 05:52:32 +00:00
}
extern "C" timepoint_ns
time_state_get_now_and_update(struct time_state *state)
2019-03-18 05:52:32 +00:00
{
assert(state != NULL);
return time_state_get_now(state);
2019-03-18 05:52:32 +00:00
}
extern "C" void
2021-01-14 14:13:48 +00:00
time_state_to_timespec(struct time_state const *state, timepoint_ns timestamp, struct timespec *out)
2019-03-18 05:52:32 +00:00
{
assert(state != NULL);
assert(out != NULL);
uint64_t ns = time_state_ts_to_monotonic_ns(state, timestamp);
out->tv_sec = ns / (U_1_000_000_000);
out->tv_nsec = ns % (U_1_000_000_000);
}
2019-03-18 05:52:32 +00:00
extern "C" timepoint_ns
2021-01-14 14:13:48 +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);
uint64_t ns = 0;
ns += timespecTime->tv_nsec;
ns += timespecTime->tv_sec * U_1_000_000_000;
2019-03-18 05:52:32 +00:00
return time_state_monotonic_to_ts_ns(state, ns);
}
2019-03-18 05:52:32 +00:00
extern "C" timepoint_ns
2021-01-14 14:13:48 +00:00
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
return monotonic_ns - state->offset;
2020-02-27 13:46:10 +00:00
}
extern "C" uint64_t
2021-01-14 14:13:48 +00:00
time_state_ts_to_monotonic_ns(struct time_state const *state, timepoint_ns timestamp)
{
assert(state != NULL);
return timestamp + state->offset;
}
#ifdef XRT_OS_WINDOWS
extern "C" void
time_state_to_win32perfcounter(struct time_state const *state, timepoint_ns timestamp, LARGE_INTEGER *out_qpc_ticks)
{
assert(state != NULL);
assert(out_qpc_ticks != NULL);
uint64_t ns = time_state_ts_to_monotonic_ns(state, timestamp);
out_qpc_ticks->QuadPart = ns / os_ns_per_qpc_tick_get();
}
extern "C" timepoint_ns
time_state_from_win32perfcounter(struct time_state const *state, const LARGE_INTEGER *qpc_ticks)
{
assert(state != NULL);
assert(qpc_ticks != NULL);
uint64_t ns = qpc_ticks->QuadPart * os_ns_per_qpc_tick_get();
return time_state_monotonic_to_ts_ns(state, ns);
}
#endif // XRT_OS_WINDOWS