Move all time support to ddsrt

* Move wctime, mtime, etime types to ddsrt

* Add ddsrt_time_wallclock

* Change ddsrt_time_monontic, elapsed to use mtime, etime types

* Remove now, now_mt, now_et

* Rename X_to_sec_usec to ddsrt_X_to_sec_usec

* add_duration_to_X to ddsrt_X_add_duration (to be in line with the
  existing ddsrt_time_add_duration)

* elimination of ddsrt/timeconv.h, it added more in the way of
  complications than it did in making things more elegant

* rename of q_time.[ch] to ddsi_time.[ch]: that now only deals with DDSI
  timestamps and durations on the wire

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-03-09 14:33:31 +01:00 committed by eboasson
parent 1611adc20a
commit 77c3545f5e
65 changed files with 757 additions and 746 deletions

View file

@ -21,6 +21,7 @@
#define DDS_TIME_H
#include <stdint.h>
#include <assert.h>
#include "dds/export.h"
#include "dds/ddsrt/types.h"
@ -69,6 +70,23 @@ typedef int64_t dds_duration_t;
#define DDS_USECS(n) ((n) * DDS_NSECS_IN_USEC)
/** @}*/
typedef struct {
dds_time_t v;
} ddsrt_mtime_t;
typedef struct {
dds_time_t v;
} ddsrt_wctime_t;
typedef struct {
dds_time_t v;
} ddsrt_etime_t;
#define DDSRT_MTIME_NEVER ((ddsrt_mtime_t) { DDS_NEVER })
#define DDSRT_WCTIME_NEVER ((ddsrt_wctime_t) { DDS_NEVER })
#define DDSRT_ETIME_NEVER ((ddsrt_etime_t) { DDS_NEVER })
#define DDSRT_WCTIME_INVALID ((ddsrt_wctime_t) { INT64_MIN })
/**
* @brief Get the current time in nanoseconds since the UNIX Epoch.
*
@ -86,6 +104,14 @@ DDS_EXPORT dds_time_t dds_time(void);
*/
DDS_EXPORT void dds_sleepfor (dds_duration_t reltime);
/**
* @brief Get the current time in nanoseconds since the UNIX Epoch. Identical
* to (ddsrt_wctime_t){dds_time()}
*
* @returns Curren time.
*/
DDS_EXPORT ddsrt_wctime_t ddsrt_time_wallclock(void);
/**
* @brief Get high resolution, monotonic time.
*
@ -99,7 +125,7 @@ DDS_EXPORT void dds_sleepfor (dds_duration_t reltime);
*
* @returns Monotonic time if available, otherwise real time.
*/
DDS_EXPORT dds_time_t ddsrt_time_monotonic(void);
DDS_EXPORT ddsrt_mtime_t ddsrt_time_monotonic(void);
/**
* @brief Get high resolution, elapsed (and thus monotonic) time since some
@ -113,7 +139,7 @@ DDS_EXPORT dds_time_t ddsrt_time_monotonic(void);
*
* @returns Elapsed time if available, otherwise return monotonic time.
*/
DDS_EXPORT dds_time_t ddsrt_time_elapsed(void);
DDS_EXPORT ddsrt_etime_t ddsrt_time_elapsed(void);
/**
* @brief Convert time into a human readable string in RFC 3339 format.
@ -135,6 +161,131 @@ DDS_EXPORT dds_time_t ddsrt_time_elapsed(void);
DDS_EXPORT size_t ddsrt_ctime(dds_time_t abstime, char *str, size_t size);
/**
* @brief Calculate a time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline dds_time_t ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime)
{
assert(abstime >= 0);
assert(reltime >= 0);
return (reltime >= DDS_NEVER - abstime ? DDS_NEVER : abstime + reltime);
}
/**
* @brief Calculate a monotonic time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_mtime_t ddsrt_mtime_add_duration(ddsrt_mtime_t abstime, dds_duration_t reltime) {
return (ddsrt_mtime_t) { ddsrt_time_add_duration (abstime.v, reltime) };
}
/**
* @brief Calculate a wall-clock time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_wctime_t ddsrt_wctime_add_duration(ddsrt_wctime_t abstime, dds_duration_t reltime) {
return (ddsrt_wctime_t) { ddsrt_time_add_duration (abstime.v, reltime) };
}
/**
* @brief Calculate an elapsed time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline ddsrt_etime_t ddsrt_etime_add_duration(ddsrt_etime_t abstime, dds_duration_t reltime) {
return (ddsrt_etime_t) { ddsrt_time_add_duration (abstime.v, reltime) };
}
#if _WIN32
/**
* @brief Convert a relative time to microseconds rounding up.
*
* @param[in] reltime Relative time to convert.
*
* @returns INFINITE if @reltime was @DDS_INIFINITY, relative time converted to
* microseconds otherwise.
*/
inline DWORD
ddsrt_duration_to_msecs_ceil(dds_duration_t reltime)
{
if (reltime == DDS_INFINITY) {
return INFINITE;
} else if (reltime > 0) {
assert(INFINITE < (DDS_INFINITY / DDS_NSECS_IN_MSEC));
dds_duration_t max_nsecs = (INFINITE - 1) * DDS_NSECS_IN_MSEC;
if (reltime < (max_nsecs - (DDS_NSECS_IN_MSEC - 1))) {
reltime += (DDS_NSECS_IN_MSEC - 1);
} else {
reltime = max_nsecs;
}
return (DWORD)(reltime / DDS_NSECS_IN_MSEC);
}
return 0;
}
#endif
/**
* @brief Convert monotonic time seconds & microseconds
*
* @param[in] t Monotonic time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_mtime_t t);
/**
* @brief Convert wall-clock time seconds & microseconds
*
* @param[in] t Wall-clock time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_wctime_t t);
/**
* @brief Convert elapsed time seconds & microseconds
*
* @param[in] t Elasped time to convert
* @param[out] sec Seconds part
* @param[out] usec Microseconds part
*/
DDS_EXPORT void ddsrt_etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_etime_t t);
#if defined(__cplusplus)
}
#endif

View file

@ -18,7 +18,6 @@
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/process.h"
#include "dds/ddsrt/timeconv.h"
ddsrt_pid_t

View file

@ -19,7 +19,7 @@
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
void ddsrt_mutex_init(ddsrt_mutex_t *mutex)
{

View file

@ -18,7 +18,7 @@
#include <sys/time.h>
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
void ddsrt_mutex_init (ddsrt_mutex_t *mutex)
{

View file

@ -18,7 +18,7 @@
#include <sys/time.h>
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
void ddsrt_mutex_init (ddsrt_mutex_t *mutex)
{

View file

@ -13,7 +13,7 @@
#include <stdlib.h>
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
void ddsrt_mutex_init(ddsrt_mutex_t *mutex)
{

View file

@ -12,11 +12,14 @@
#include <assert.h>
#include <time.h>
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/static_assert.h"
extern inline dds_time_t
ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime);
extern inline dds_time_t ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime);
extern inline ddsrt_mtime_t ddsrt_mtime_add_duration(ddsrt_mtime_t abstime, dds_duration_t reltime);
extern inline ddsrt_wctime_t ddsrt_wctime_add_duration(ddsrt_wctime_t abstime, dds_duration_t reltime);
extern inline ddsrt_etime_t ddsrt_etime_add_duration(ddsrt_etime_t abstime, dds_duration_t reltime);
#if !_WIN32 && !DDSRT_WITH_FREERTOS
#include <errno.h>
@ -71,3 +74,23 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size)
return ddsrt_strlcpy(str, buf, size);
}
static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t)
{
*sec = (int32_t) (t / DDS_NSECS_IN_SEC);
*usec = (int32_t) (t % DDS_NSECS_IN_SEC) / 1000;
}
void ddsrt_mtime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_mtime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void ddsrt_wctime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_wctime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}
void ddsrt_etime_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, ddsrt_etime_t t)
{
time_to_sec_usec (sec, usec, t.v);
}

View file

@ -32,10 +32,15 @@ dds_time_t dds_time(void)
#endif
}
dds_time_t ddsrt_time_monotonic(void)
ddsrt_wctime_t ddsrt_time_wallclock(void)
{
return (ddsrt_wctime_t) { dds_time () };
}
ddsrt_mtime_t ddsrt_time_monotonic(void)
{
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_UPTIME_RAW);
return (ddsrt_mtime_t) { (int64_t) clock_gettime_nsec_np (CLOCK_UPTIME_RAW) };
#else
static mach_timebase_info_data_t timeInfo;
uint64_t mt;
@ -57,16 +62,17 @@ dds_time_t ddsrt_time_monotonic(void)
(void)mach_timebase_info(&timeInfo);
}
return (dds_time_t)(mt * timeInfo.numer / timeInfo.denom);
return (ddsrt_mtime_t) { mt * timeInfo.numer / timeInfo.denom };
#endif
}
dds_time_t ddsrt_time_elapsed(void)
ddsrt_etime_t ddsrt_time_elapsed(void)
{
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_MONOTONIC_RAW);
return (ddsrt_etime_t) { (int64_t) clock_gettime_nsec_np (CLOCK_MONOTONIC_RAW) };
#else
/* Elapsed time clock not (yet) supported on this platform. */
return ddsrt_time_monotonic();
dds_mtime_t mt = ddsrt_time_monotonic();
return (ddsrt_etime_t) { mt.v };
#endif
}

View file

@ -33,15 +33,20 @@ dds_time_t dds_time(void)
#define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ)
dds_time_t ddsrt_time_monotonic (void)
ddsrt_wctime_t ddsrt_time_wallclock (void)
{
return (xTaskGetTickCount() * NSECS_PER_TICK);
return (ddsrt_wctime_t) { dds_time() };
}
dds_time_t ddsrt_time_elapsed (void)
ddsrt_mtime_t ddsrt_time_monotonic (void)
{
return (ddsrt_mtime_t) { xTaskGetTickCount() * NSECS_PER_TICK };
}
ddsrt_etime_t ddsrt_time_elapsed (void)
{
/* Elapsed time clock not (yet) supported on this platform. */
return ddsrt_time_monotonic ();
return (ddsrt_etime_t) { xTaskGetTickCount() * NSECS_PER_TICK };
}
void dds_sleepfor (dds_duration_t reltime)

View file

@ -15,54 +15,3 @@
#include "dds/ddsrt/misc.h"
#include "dds/ddsrt/time.h"
/**
* @brief Calculate a time given an offset time and a duration.
*
* Negative time can become positive by adding a large enough duration, of
* course a positive time can become negative given a large enough negative
* duration.
*
* @param[in] abstime Timestamp in nanoseconds since UNIX Epoch.
* @param[in] reltime Relative time in nanoseconds.
*
* @returns A timestamp in nanoseconds since UNIX Epoch.
*/
inline dds_time_t
ddsrt_time_add_duration(dds_time_t abstime, dds_duration_t reltime)
{
assert(abstime >= 0);
assert(reltime >= 0);
return (reltime >= DDS_NEVER - abstime ? DDS_NEVER : abstime + reltime);
}
#if _WIN32
/**
* @brief Convert a relative time to microseconds rounding up.
*
* @param[in] reltime Relative time to convert.
*
* @returns INFINITE if @reltime was @DDS_INIFINITY, relative time converted to
* microseconds otherwise.
*/
inline DWORD
ddsrt_duration_to_msecs_ceil(dds_duration_t reltime)
{
if (reltime == DDS_INFINITY) {
return INFINITE;
} else if (reltime > 0) {
assert(INFINITE < (DDS_INFINITY / DDS_NSECS_IN_MSEC));
dds_duration_t max_nsecs = (INFINITE - 1) * DDS_NSECS_IN_MSEC;
if (reltime < (max_nsecs - (DDS_NSECS_IN_MSEC - 1))) {
reltime += (DDS_NSECS_IN_MSEC - 1);
} else {
reltime = max_nsecs;
}
return (DWORD)(reltime / DDS_NSECS_IN_MSEC);
}
return 0;
}
#endif

View file

@ -21,21 +21,28 @@
dds_time_t dds_time(void)
{
struct timespec ts;
(void)clock_gettime(CLOCK_REALTIME, &ts);
return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec;
}
dds_time_t ddsrt_time_monotonic(void)
ddsrt_wctime_t ddsrt_time_wallclock(void)
{
struct timespec ts;
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec;
(void)clock_gettime(CLOCK_REALTIME, &ts);
return (ddsrt_wctime_t) { (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec };
}
dds_time_t ddsrt_time_elapsed(void)
ddsrt_mtime_t ddsrt_time_monotonic(void)
{
struct timespec ts;
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
return (ddsrt_mtime_t) { (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec };
}
ddsrt_etime_t ddsrt_time_elapsed(void)
{
/* Elapsed time clock not worth the bother for now. */
return ddsrt_time_monotonic();
struct timespec ts;
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
return (ddsrt_etime_t) { (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec };
}

View file

@ -26,13 +26,17 @@ dds_time_t dds_time(void)
return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec;
}
dds_time_t ddsrt_time_monotonic(void)
ddsrt_wctime_t ddsrt_time_wallclock(void)
{
return gethrtime ();
return (ddsrt_wctime_t) { dds_time() };
}
dds_time_t ddsrt_time_elapsed(void)
ddsrt_mtime_t ddsrt_time_monotonic(void)
{
/* Elapsed time clock not worth the bother for now. */
return ddsrt_time_monotonic();
return (ddsrt_mtime_t) { gethrtime () };
}
ddsrt_etime_t ddsrt_time_elapsed(void)
{
return (ddsrt_etime_t) { gethrtime () };
}

View file

@ -13,7 +13,7 @@
#include <sys/timeb.h>
#include <time.h>
#include "dds/ddsrt/timeconv.h"
#include "dds/ddsrt/time.h"
extern inline DWORD
ddsrt_duration_to_msecs_ceil(dds_duration_t reltime);
@ -100,16 +100,21 @@ void ddsrt_time_fini(void)
#endif
}
dds_time_t ddsrt_time_monotonic(void)
ddsrt_wctime_t ddsrt_time_wallclock(void)
{
return (ddsrt_wctime_t) { dds_time() } ;
}
ddsrt_mtime_t ddsrt_time_monotonic(void)
{
ULONGLONG ubit;
(void)QueryUnbiasedInterruptTime(&ubit); /* 100ns ticks */
return (dds_time_t)(ubit * 100);
return (ddsrt_mtime_t) { ubit * 100 };
}
dds_time_t ddsrt_time_elapsed(void)
ddsrt_etime_t ddsrt_time_elapsed(void)
{
LARGE_INTEGER qpc;
static LONGLONG qpc_freq; /* Counts per nanosecond. */
@ -152,7 +157,7 @@ dds_time_t ddsrt_time_elapsed(void)
* the time progression to actual time progression. */
QueryPerformanceCounter(&qpc);
return (dds_time_t)(qpc.QuadPart * qpc_freq);
return (ddsrt_etime_t) { qpc.QuadPart * qpc_freq };
}
void dds_sleepfor(dds_duration_t reltime)

View file

@ -167,7 +167,7 @@ CU_Theory ((const struct ops *ops, bool random, adj_fun_t adj, const char *adjna
void *h = ops->new ();
uint32_t i, nk = 0;
uint64_t nn = 0;
dds_time_t t0, t1;
ddsrt_mtime_t t0, t1;
t0 = ddsrt_time_monotonic ();
for (uint32_t iter = 0; iter < MAX_ITERS; iter++)
{
@ -205,5 +205,5 @@ CU_Theory ((const struct ops *ops, bool random, adj_fun_t adj, const char *adjna
}
t1 = ddsrt_time_monotonic ();
ops->free (h);
printf (" %"PRIu64" %.0f ns/cycle\n", nn, (double) (t1 - t0) / (double) nn);
printf (" %"PRIu64" %.0f ns/cycle\n", nn, (double) (t1.v - t0.v) / (double) nn);
}