Skip to content

Commit aebda26

Browse files
committed
Add ddsrt_hrtime_t / ddsrt_time_highres
Some platforms (QNX is an example) have low-resolution clocks that one can use for timeouts, and high-resolution clocks that cannot be used for that. This introduces a separate "high resolution" time that can be used only for computing time elapsed between two events. Signed-off-by: Erik Boasson <[email protected]>
1 parent fb191bd commit aebda26

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

src/ddsrt/include/dds/ddsrt/time.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ typedef struct {
8686
dds_time_t v;
8787
} ddsrt_etime_t;
8888

89+
typedef struct {
90+
uint64_t v;
91+
} ddsrt_hrtime_t;
92+
8993
#define DDSRT_MTIME_NEVER ((ddsrt_mtime_t) { DDS_NEVER })
9094
#define DDSRT_WCTIME_NEVER ((ddsrt_wctime_t) { DDS_NEVER })
9195
#define DDSRT_ETIME_NEVER ((ddsrt_etime_t) { DDS_NEVER })
@@ -145,6 +149,20 @@ DDS_EXPORT ddsrt_mtime_t ddsrt_time_monotonic(void);
145149
*/
146150
DDS_EXPORT ddsrt_etime_t ddsrt_time_elapsed(void);
147151

152+
/**
153+
* @brief Get high resolution, elapsed (and thus monotonic) time since some
154+
* fixed unspecified past time.
155+
*
156+
* The elapsed time clock is a clock with near real-time progression and can be
157+
* used when a high-resolution suspend-aware monotonic clock is needed, without
158+
* having to deal with the complications of discontinuities if for example the
159+
* time is changed. The fixed point from which the elapsed time is returned is
160+
* not guaranteed to be fixed over reboots of the system.
161+
*
162+
* @returns Elapsed time if available, otherwise return monotonic time.
163+
*/
164+
DDS_EXPORT ddsrt_hrtime_t ddsrt_time_highres(void);
165+
148166
/**
149167
* @brief Convert time into a human readable string in RFC 3339 format.
150168
*

src/ddsrt/src/time/darwin/time.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,9 @@ ddsrt_etime_t ddsrt_time_elapsed(void)
7575
return (ddsrt_etime_t) { mt.v };
7676
#endif
7777
}
78+
79+
ddsrt_hrtime_t ddsrt_time_highres(void)
80+
{
81+
ddsrt_mtime_t mt = ddsrt_time_monotonic();
82+
return (ddsrt_hrtime_t) { (uint64_t) mt.v };
83+
}

src/ddsrt/src/time/posix/time.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
#include <time.h>
1616
#include <sys/time.h>
1717

18+
#ifdef __QNXNTO__
19+
#include <sys/neutrino.h>
20+
#include <sys/syspage.h>
21+
#endif
22+
1823
#include "dds/ddsrt/time.h"
1924

2025
dds_time_t dds_time(void)
@@ -45,3 +50,20 @@ ddsrt_etime_t ddsrt_time_elapsed(void)
4550
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
4651
return (ddsrt_etime_t) { (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec };
4752
}
53+
54+
ddsrt_hrtime_t ddsrt_time_highres(void)
55+
{
56+
#ifdef __QNXNTO__
57+
static uint64_t freq = 0;
58+
static uint64_t multiplier = 0;
59+
if (freq == 0) {
60+
freq = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
61+
multiplier = (uint64_t) DDS_NSECS_IN_SEC / freq;
62+
}
63+
uint64_t cycles = ClockCycles ();
64+
return (ddsrt_hrtime_t) { cycles * multiplier };
65+
#else
66+
ddsrt_mtime_t mt = ddsrt_time_monotonic();
67+
return (ddsrt_hrtime_t) { (uint64_t) mt.v };
68+
#endif
69+
}

src/ddsrt/src/time/solaris2.6/time.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,8 @@ ddsrt_etime_t ddsrt_time_elapsed(void)
3939
{
4040
return (ddsrt_etime_t) { gethrtime () };
4141
}
42+
43+
ddsrt_hrtime_t ddsrt_time_highres(void)
44+
{
45+
return (ddsrt_hrtime_t) { gethrtime () };
46+
}

src/ddsrt/src/time/windows/time.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ ddsrt_wctime_t ddsrt_time_wallclock(void)
113113
ddsrt_mtime_t ddsrt_time_monotonic(void)
114114
{
115115
ULONGLONG ubit;
116-
117116
(void)QueryUnbiasedInterruptTime(&ubit); /* 100ns ticks */
118-
119117
return (ddsrt_mtime_t) { (dds_time_t)ubit * 100 };
120118
}
121119

@@ -165,6 +163,13 @@ ddsrt_etime_t ddsrt_time_elapsed(void)
165163
return (ddsrt_etime_t) { qpc.QuadPart * qpc_freq };
166164
}
167165

166+
ddsrt_hrtime_t ddsrt_time_highres(void)
167+
{
168+
ULONGLONG ubit;
169+
(void)QueryUnbiasedInterruptTime(&ubit); /* 100ns ticks */
170+
return (ddsrt_hrtime_t) { ubit * 100 };
171+
}
172+
168173
void dds_sleepfor (dds_duration_t timeout)
169174
{
170175
DWORD msecs;

0 commit comments

Comments
 (0)