time-util: add triple timestamp object
We already have a double timestamp object that we use whenever we need both a MONOTONIC and a REALTIME timestamp taken and stored. With this change we also add a triple timestamp object that in addition stores a BOOTTIME timestamp, which is useful for a few usecases. Note that we keep dual_timestamp around, as it is useful in many cases where triple_timestamp is not, in particular because retrieving the monotonic and realtime timestamps is much cheaper on Linux that getting the boottime timestamp.
This commit is contained in:
@@ -87,6 +87,16 @@ dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
|
||||
return ts;
|
||||
}
|
||||
|
||||
triple_timestamp* triple_timestamp_get(triple_timestamp *ts) {
|
||||
assert(ts);
|
||||
|
||||
ts->realtime = now(CLOCK_REALTIME);
|
||||
ts->monotonic = now(CLOCK_MONOTONIC);
|
||||
ts->boottime = clock_boottime_supported() ? now(CLOCK_BOOTTIME) : USEC_INFINITY;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
|
||||
int64_t delta;
|
||||
assert(ts);
|
||||
@@ -104,6 +114,24 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
|
||||
return ts;
|
||||
}
|
||||
|
||||
triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) {
|
||||
int64_t delta;
|
||||
|
||||
assert(ts);
|
||||
|
||||
if (u == USEC_INFINITY || u <= 0) {
|
||||
ts->realtime = ts->monotonic = ts->boottime = u;
|
||||
return ts;
|
||||
}
|
||||
|
||||
ts->realtime = u;
|
||||
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
|
||||
ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
|
||||
ts->boottime = clock_boottime_supported() ? usec_sub(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
|
||||
int64_t delta;
|
||||
assert(ts);
|
||||
@@ -136,6 +164,26 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
|
||||
return ts;
|
||||
}
|
||||
|
||||
usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock) {
|
||||
|
||||
switch (clock) {
|
||||
|
||||
case CLOCK_REALTIME:
|
||||
case CLOCK_REALTIME_ALARM:
|
||||
return ts->realtime;
|
||||
|
||||
case CLOCK_MONOTONIC:
|
||||
return ts->monotonic;
|
||||
|
||||
case CLOCK_BOOTTIME:
|
||||
case CLOCK_BOOTTIME_ALARM:
|
||||
return ts->boottime;
|
||||
|
||||
default:
|
||||
return USEC_INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
usec_t timespec_load(const struct timespec *ts) {
|
||||
assert(ts);
|
||||
|
||||
@@ -1107,6 +1155,30 @@ clockid_t clock_boottime_or_monotonic(void) {
|
||||
return CLOCK_MONOTONIC;
|
||||
}
|
||||
|
||||
bool clock_supported(clockid_t clock) {
|
||||
struct timespec ts;
|
||||
|
||||
switch (clock) {
|
||||
|
||||
case CLOCK_MONOTONIC:
|
||||
case CLOCK_REALTIME:
|
||||
return true;
|
||||
|
||||
case CLOCK_BOOTTIME:
|
||||
return clock_boottime_supported();
|
||||
|
||||
case CLOCK_BOOTTIME_ALARM:
|
||||
if (!clock_boottime_supported())
|
||||
return false;
|
||||
|
||||
/* fall through, after checking the cached value for CLOCK_BOOTTIME. */
|
||||
|
||||
default:
|
||||
/* For everything else, check properly */
|
||||
return clock_gettime(clock, &ts) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
int get_timezone(char **tz) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *e;
|
||||
|
||||
Reference in New Issue
Block a user