Add newtypes for absolute and relative time
This commit is contained in:
parent
d0bcd6b20c
commit
d3a3217e88
13
events.c
13
events.c
|
@ -37,20 +37,15 @@ event_create(const EventData * content)
|
||||||
event->data = *content;
|
event->data = *content;
|
||||||
event->data.modifiers = modifier_set_copy(content->modifiers);
|
event->data.modifiers = modifier_set_copy(content->modifiers);
|
||||||
} else {
|
} else {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &event->data.time);
|
event->data.time = get_current_time();
|
||||||
}
|
}
|
||||||
struct timespec self_time = event->data.time;
|
AbsoluteTime self_time = event->data.time;
|
||||||
EventNode ** list_pos = &LAST_EVENT;
|
EventNode ** list_pos = &LAST_EVENT;
|
||||||
FOREACH_EVENT_DESC(other) {
|
FOREACH_EVENT_DESC(other) {
|
||||||
struct timespec other_time = other->data.time;
|
AbsoluteTime other_time = other->data.time;
|
||||||
if (self_time.tv_sec > other_time.tv_sec) {
|
if (absolute_time_cmp(self_time, other_time) >= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (self_time.tv_sec == other_time.tv_sec) {
|
|
||||||
if (self_time.tv_nsec >= other_time.tv_nsec) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list_pos = &other->next->prev;
|
list_pos = &other->next->prev;
|
||||||
}
|
}
|
||||||
EventNode * prev = *list_pos;
|
EventNode * prev = *list_pos;
|
||||||
|
|
4
events.h
4
events.h
|
@ -1,9 +1,9 @@
|
||||||
#ifndef EVENTS_H_
|
#ifndef EVENTS_H_
|
||||||
#define EVENTS_H_
|
#define EVENTS_H_
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "modifiers.h"
|
#include "modifiers.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
typedef uint32_t EventNamespace;
|
typedef uint32_t EventNamespace;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ typedef struct {
|
||||||
int32_t priority;
|
int32_t priority;
|
||||||
int64_t payload;
|
int64_t payload;
|
||||||
ModifierSet modifiers;
|
ModifierSet modifiers;
|
||||||
struct timespec time;
|
AbsoluteTime time;
|
||||||
} EventData;
|
} EventData;
|
||||||
|
|
||||||
typedef struct event_position_base EventPositionBase;
|
typedef struct event_position_base EventPositionBase;
|
||||||
|
|
2
main.c
2
main.c
|
@ -10,8 +10,8 @@ main(int argc, char ** argv)
|
||||||
|
|
||||||
ProcessingState state = (ProcessingState) {
|
ProcessingState state = (ProcessingState) {
|
||||||
.wait_delay = NULL,
|
.wait_delay = NULL,
|
||||||
|
.reached_time = get_current_time(),
|
||||||
};
|
};
|
||||||
clock_gettime(CLOCK_MONOTONIC, &state.reached_time);
|
|
||||||
io_subscription_list_init(&state.wait_input, 5);
|
io_subscription_list_init(&state.wait_input, 5);
|
||||||
io_subscription_list_init(&state.wait_output, 5);
|
io_subscription_list_init(&state.wait_output, 5);
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ handle_io(EventPositionBase * self, int fd, bool is_output)
|
||||||
.priority = 10,
|
.priority = 10,
|
||||||
.payload = buf[0],
|
.payload = buf[0],
|
||||||
.modifiers = EMPTY_MODIFIER_SET,
|
.modifiers = EMPTY_MODIFIER_SET,
|
||||||
|
.time = get_current_time(),
|
||||||
};
|
};
|
||||||
clock_gettime(CLOCK_MONOTONIC, &data.time);
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
node->subscription.enabled = false;
|
node->subscription.enabled = false;
|
||||||
data.code.value = 2;
|
data.code.value = 2;
|
||||||
|
|
|
@ -18,7 +18,7 @@ handle_event(EventPositionBase * self, EventNode * event)
|
||||||
printf("%02x", data.modifiers.bits[i]);
|
printf("%02x", data.modifiers.bits[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("time = %ld.%09ld\n", data.time.tv_sec, data.time.tv_nsec);
|
printf("time.absolute = %ld.%09ld\n", data.time.absolute.tv_sec, data.time.absolute.tv_nsec);
|
||||||
printf("---\n\n");
|
printf("---\n\n");
|
||||||
event_destroy(event);
|
event_destroy(event);
|
||||||
return true;
|
return true;
|
||||||
|
|
97
processing.c
97
processing.c
|
@ -117,7 +117,7 @@ run_io_handlers(fd_set * fds, IOSubscriptionList * subs, bool arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
process_io(ProcessingState * state, const struct timespec * timeout)
|
process_io(ProcessingState * state, const RelativeTime * timeout)
|
||||||
{
|
{
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
fd_set readfds, writefds;
|
fd_set readfds, writefds;
|
||||||
|
@ -126,7 +126,7 @@ process_io(ProcessingState * state, const struct timespec * timeout)
|
||||||
max_fd = populate_fd_set(&writefds, &state->wait_output, max_fd);
|
max_fd = populate_fd_set(&writefds, &state->wait_output, max_fd);
|
||||||
|
|
||||||
++max_fd;
|
++max_fd;
|
||||||
int ready = pselect(max_fd, &readfds, &writefds, NULL, timeout, NULL);
|
int ready = pselect(max_fd, &readfds, &writefds, NULL, &timeout->relative, NULL);
|
||||||
|
|
||||||
if (ready < 0) {
|
if (ready < 0) {
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
|
@ -143,19 +143,14 @@ process_io(ProcessingState * state, const struct timespec * timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
schedule_delay(ProcessingState * state, EventPositionBase * target, void (*callback) (EventPositionBase*, void*, const struct timespec*), const struct timespec * time)
|
schedule_delay(ProcessingState * state, EventPositionBase * target, void (*callback) (EventPositionBase*, void*, const AbsoluteTime*), const AbsoluteTime * time)
|
||||||
{
|
{
|
||||||
DelayList **next = &state->wait_delay;
|
DelayList **next = &state->wait_delay;
|
||||||
while (*next) {
|
while (*next) {
|
||||||
struct timespec next_time = (*next)->time;
|
AbsoluteTime next_time = (*next)->time;
|
||||||
if (next_time.tv_sec > time->tv_sec) {
|
if (absolute_time_cmp(next_time, *time) > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (next_time.tv_sec == time->tv_sec) {
|
|
||||||
if (next_time.tv_nsec > time->tv_nsec) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next = &((*next)->next);
|
next = &((*next)->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,33 +169,22 @@ schedule_delay(ProcessingState * state, EventPositionBase * target, void (*callb
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct timespec ZERO_TS = {
|
static const RelativeTime ZERO_TO = {
|
||||||
.tv_sec = 0,
|
.relative ={
|
||||||
.tv_nsec = 0,
|
.tv_sec = 0,
|
||||||
|
.tv_nsec = 0,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static void
|
|
||||||
fix_nsec(struct timespec * ts)
|
|
||||||
{
|
|
||||||
if (ts->tv_nsec < 0) {
|
|
||||||
ts->tv_nsec += 1000000000;
|
|
||||||
ts->tv_sec -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
process_single_scheduled(ProcessingState * state, const struct timespec extern_time)
|
process_single_scheduled(ProcessingState * state, const AbsoluteTime extern_time)
|
||||||
{
|
{
|
||||||
if (!state->wait_delay) {
|
if (!state->wait_delay) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
struct timespec next_scheduled_time = state->wait_delay->time; // abs
|
AbsoluteTime next_scheduled_time = state->wait_delay->time;
|
||||||
if (next_scheduled_time.tv_sec > extern_time.tv_sec) {
|
if (absolute_time_cmp(next_scheduled_time, extern_time) > 0) {
|
||||||
return false;
|
return false;
|
||||||
} else if (next_scheduled_time.tv_sec == extern_time.tv_sec) {
|
|
||||||
if (next_scheduled_time.tv_nsec > extern_time.tv_nsec) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DelayList next_scheduled = *state->wait_delay;
|
DelayList next_scheduled = *state->wait_delay;
|
||||||
free(state->wait_delay);
|
free(state->wait_delay);
|
||||||
|
@ -217,7 +201,7 @@ process_single_scheduled(ProcessingState * state, const struct timespec extern_t
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
process_events_until(ProcessingState * state, const struct timespec * max_time)
|
process_events_until(ProcessingState * state, const AbsoluteTime * max_time)
|
||||||
{
|
{
|
||||||
bool stable = true;
|
bool stable = true;
|
||||||
int32_t next_priority = INT32_MIN;
|
int32_t next_priority = INT32_MIN;
|
||||||
|
@ -225,17 +209,11 @@ process_events_until(ProcessingState * state, const struct timespec * max_time)
|
||||||
|
|
||||||
FOREACH_EVENT(ev) {
|
FOREACH_EVENT(ev) {
|
||||||
if (max_time) {
|
if (max_time) {
|
||||||
struct timespec ev_time = ev->data.time;
|
AbsoluteTime ev_time = ev->data.time;
|
||||||
if (ev_time.tv_sec > max_time->tv_sec) {
|
if (absolute_time_cmp(ev_time, *max_time) > 0) {
|
||||||
// stable = false;
|
// stable = false;
|
||||||
state->has_future_events = true;
|
state->has_future_events = true;
|
||||||
break;
|
break;
|
||||||
} else if (ev_time.tv_sec == max_time->tv_sec) {
|
|
||||||
if (ev_time.tv_nsec > max_time->tv_nsec) {
|
|
||||||
// stable = false;
|
|
||||||
state->has_future_events = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,15 +248,10 @@ process_events_until(ProcessingState * state, const struct timespec * max_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_time) {
|
if (max_time) {
|
||||||
struct timespec ev_time = ev->data.time;
|
AbsoluteTime ev_time = ev->data.time;
|
||||||
if (ev_time.tv_sec > max_time->tv_sec) {
|
if (absolute_time_cmp(ev_time, *max_time) > 0) {
|
||||||
state->has_future_events = true;
|
state->has_future_events = true;
|
||||||
break;
|
break;
|
||||||
} else if (ev_time.tv_sec == max_time->tv_sec) {
|
|
||||||
if (ev_time.tv_nsec > max_time->tv_nsec) {
|
|
||||||
state->has_future_events = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,28 +277,21 @@ process_events_until(ProcessingState * state, const struct timespec * max_time)
|
||||||
void
|
void
|
||||||
process_iteration(ProcessingState * state)
|
process_iteration(ProcessingState * state)
|
||||||
{
|
{
|
||||||
struct timespec extern_time;
|
AbsoluteTime extern_time = get_current_time();
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &extern_time) < 0) {
|
|
||||||
perror("Failed to get time");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// late_by.tv_sec = extern_time.tv_sec - state->reached_time.tv_sec;
|
// late_by.tv_sec = extern_time.tv_sec - state->reached_time.tv_sec;
|
||||||
// late_by.tv_nsec = extern_time.tv_nsec - state->reached_time.tv_nsec;
|
// late_by.tv_nsec = extern_time.tv_nsec - state->reached_time.tv_nsec;
|
||||||
// fix_nsec(&late_by);
|
// fix_nsec(&late_by);
|
||||||
|
|
||||||
struct timespec next_scheduled_delay;
|
RelativeTime next_scheduled_delay;
|
||||||
const struct timespec *max_io_timeout = NULL;
|
const RelativeTime *max_io_timeout = NULL;
|
||||||
if (state->has_future_events) {
|
if (state->has_future_events) {
|
||||||
max_io_timeout = &ZERO_TS;
|
max_io_timeout = &ZERO_TO;
|
||||||
} else {
|
} else {
|
||||||
if (state->wait_delay) {
|
if (state->wait_delay) {
|
||||||
next_scheduled_delay = state->wait_delay->time; // abs
|
next_scheduled_delay = absolute_time_sub_absolute(state->wait_delay->time, extern_time);
|
||||||
next_scheduled_delay.tv_sec -= extern_time.tv_sec;
|
if (relative_time_cmp(next_scheduled_delay, ZERO_TO) < 0) {
|
||||||
next_scheduled_delay.tv_nsec -= extern_time.tv_nsec;
|
max_io_timeout = &ZERO_TO;
|
||||||
fix_nsec(&next_scheduled_delay);
|
|
||||||
if (next_scheduled_delay.tv_sec < 0) {
|
|
||||||
max_io_timeout = &ZERO_TS;
|
|
||||||
} else {
|
} else {
|
||||||
max_io_timeout = &next_scheduled_delay;
|
max_io_timeout = &next_scheduled_delay;
|
||||||
}
|
}
|
||||||
|
@ -334,19 +300,16 @@ process_iteration(ProcessingState * state)
|
||||||
|
|
||||||
// FIXME reason about timeouts
|
// FIXME reason about timeouts
|
||||||
process_io(state, max_io_timeout);
|
process_io(state, max_io_timeout);
|
||||||
// process_io(state, &ZERO_TS);
|
// process_io(state, &ZERO_TO);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool had_scheduled = process_single_scheduled(state, extern_time);
|
bool had_scheduled = process_single_scheduled(state, extern_time);
|
||||||
const struct timespec *max_event_time = &extern_time;
|
const AbsoluteTime *max_event_time = &extern_time;
|
||||||
if (state->wait_delay) {
|
if (state->wait_delay) {
|
||||||
struct timespec next_scheduled_time = state->wait_delay->time;
|
AbsoluteTime next_scheduled_time = state->wait_delay->time;
|
||||||
bool use_scheduled = false;
|
bool use_scheduled = false;
|
||||||
if (!use_scheduled) {
|
if (!use_scheduled) {
|
||||||
use_scheduled = next_scheduled_time.tv_sec > extern_time.tv_sec;
|
use_scheduled = absolute_time_cmp(next_scheduled_time, extern_time) > 0;
|
||||||
}
|
|
||||||
if (!use_scheduled) {
|
|
||||||
use_scheduled = next_scheduled_time.tv_nsec > extern_time.tv_nsec;
|
|
||||||
}
|
}
|
||||||
if (use_scheduled) {
|
if (use_scheduled) {
|
||||||
max_event_time = &state->wait_delay->time;
|
max_event_time = &state->wait_delay->time;
|
||||||
|
@ -356,6 +319,6 @@ process_iteration(ProcessingState * state)
|
||||||
if (!had_scheduled && !had_events) {
|
if (!had_scheduled && !had_events) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
process_io(state, &ZERO_TS);
|
process_io(state, &ZERO_TO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
processing.h
10
processing.h
|
@ -23,17 +23,17 @@ typedef struct {
|
||||||
typedef struct delay_list DelayList;
|
typedef struct delay_list DelayList;
|
||||||
|
|
||||||
struct delay_list {
|
struct delay_list {
|
||||||
void (*callback) (EventPositionBase * target, void * closure, const struct timespec * time);
|
void (*callback) (EventPositionBase * target, void * closure, const AbsoluteTime * time);
|
||||||
EventPositionBase *target;
|
EventPositionBase *target;
|
||||||
void *closure;
|
void *closure;
|
||||||
DelayList *next;
|
DelayList *next;
|
||||||
struct timespec time;
|
AbsoluteTime time;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IOSubscriptionList wait_input, wait_output;
|
IOSubscriptionList wait_input, wait_output;
|
||||||
DelayList *wait_delay;
|
DelayList *wait_delay;
|
||||||
struct timespec reached_time;
|
AbsoluteTime reached_time;
|
||||||
int32_t pass_priority;
|
int32_t pass_priority;
|
||||||
bool has_future_events;
|
bool has_future_events;
|
||||||
} ProcessingState;
|
} ProcessingState;
|
||||||
|
@ -42,8 +42,8 @@ void io_subscription_list_init(IOSubscriptionList * lst, size_t capacity);
|
||||||
void io_subscription_list_deinit(IOSubscriptionList * lst);
|
void io_subscription_list_deinit(IOSubscriptionList * lst);
|
||||||
void io_subscription_list_add(IOSubscriptionList * lst, int fd, IOHandling *subscriber);
|
void io_subscription_list_add(IOSubscriptionList * lst, int fd, IOHandling *subscriber);
|
||||||
|
|
||||||
bool schedule_delay(ProcessingState * state, EventPositionBase * target, void (*callback) (EventPositionBase*, void*, const struct timespec*), const struct timespec * time);
|
bool schedule_delay(ProcessingState * state, EventPositionBase * target, void (*callback) (EventPositionBase*, void*, const AbsoluteTime*), const AbsoluteTime * time);
|
||||||
bool process_io(ProcessingState * state, const struct timespec * timeout);
|
bool process_io(ProcessingState * state, const RelativeTime * timeout);
|
||||||
void process_iteration(ProcessingState * state);
|
void process_iteration(ProcessingState * state);
|
||||||
|
|
||||||
#endif /* end of include guard: PROCESSING_H_ */
|
#endif /* end of include guard: PROCESSING_H_ */
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
#ifndef TIME_H_
|
||||||
|
#define TIME_H_
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#define NANOSECONDS_IN_SECOND 1000000000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct timespec absolute;
|
||||||
|
} AbsoluteTime;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct timespec relative;
|
||||||
|
} RelativeTime;
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static void
|
||||||
|
timespec_add(struct timespec *accum, const struct timespec *item)
|
||||||
|
{
|
||||||
|
accum->tv_sec += item->tv_sec;
|
||||||
|
accum->tv_nsec += item->tv_nsec;
|
||||||
|
while (accum->tv_nsec >= NANOSECONDS_IN_SECOND) {
|
||||||
|
++(accum->tv_sec);
|
||||||
|
accum->tv_nsec -= NANOSECONDS_IN_SECOND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static void
|
||||||
|
timespec_sub(struct timespec *accum, const struct timespec *item)
|
||||||
|
{
|
||||||
|
accum->tv_sec -= item->tv_sec;
|
||||||
|
accum->tv_nsec -= item->tv_nsec;
|
||||||
|
while (accum->tv_nsec < 0) {
|
||||||
|
--(accum->tv_sec);
|
||||||
|
accum->tv_nsec += NANOSECONDS_IN_SECOND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static int
|
||||||
|
timespec_cmp(const struct timespec *lhs, const struct timespec *rhs)
|
||||||
|
{
|
||||||
|
if (lhs->tv_sec > rhs->tv_sec) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (lhs->tv_sec < rhs->tv_sec) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (lhs->tv_nsec > rhs->tv_nsec) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (lhs->tv_nsec < rhs->tv_nsec) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static AbsoluteTime
|
||||||
|
get_current_time()
|
||||||
|
{
|
||||||
|
AbsoluteTime time;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &time.absolute) < 0) {
|
||||||
|
time.absolute.tv_sec = 0;
|
||||||
|
time.absolute.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static AbsoluteTime
|
||||||
|
absolute_time_add_relative(AbsoluteTime lhs, RelativeTime rhs)
|
||||||
|
{
|
||||||
|
timespec_add(&lhs.absolute, &rhs.relative);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static AbsoluteTime
|
||||||
|
absolute_time_sub_relative(AbsoluteTime lhs, RelativeTime rhs)
|
||||||
|
{
|
||||||
|
timespec_sub(&lhs.absolute, &rhs.relative);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static RelativeTime
|
||||||
|
absolute_time_sub_absolute(AbsoluteTime lhs, AbsoluteTime rhs)
|
||||||
|
{
|
||||||
|
RelativeTime result = {
|
||||||
|
.relative = lhs.absolute,
|
||||||
|
};
|
||||||
|
timespec_sub(&result.relative, &rhs.absolute);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static RelativeTime
|
||||||
|
relative_time_add(RelativeTime lhs, RelativeTime rhs)
|
||||||
|
{
|
||||||
|
timespec_add(&lhs.relative, &rhs.relative);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static RelativeTime
|
||||||
|
relative_time_sub(RelativeTime lhs, RelativeTime rhs)
|
||||||
|
{
|
||||||
|
timespec_sub(&lhs.relative, &rhs.relative);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static int
|
||||||
|
absolute_time_cmp(AbsoluteTime lhs, AbsoluteTime rhs)
|
||||||
|
{
|
||||||
|
return timespec_cmp(&lhs.absolute, &rhs.absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((unused)) inline static int
|
||||||
|
relative_time_cmp(RelativeTime lhs, RelativeTime rhs)
|
||||||
|
{
|
||||||
|
return timespec_cmp(&lhs.relative, &rhs.relative);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* end of include guard: TIME_H_ */
|
Loading…
Reference in New Issue