event-sequence-transformation/time.h

157 lines
3.5 KiB
C

#ifndef TIME_H_
#define TIME_H_
#include <time.h>
#define NANOSECONDS_IN_SECOND 1000000000
#define MILLISECONDS_IN_SECOND 1000
typedef struct {
struct timespec absolute;
} AbsoluteTime;
typedef struct {
struct timespec relative;
} RelativeTime;
__attribute__((unused)) inline static void
timespec_assign_nanosecond(struct timespec *target, long long ns)
{
time_t sec = ns / NANOSECONDS_IN_SECOND;
if (ns < 0) {
sec -= 1;
}
target->tv_sec = sec;
target->tv_nsec = ns - sec * NANOSECONDS_IN_SECOND;
}
__attribute__((unused)) inline static void
timespec_assign_millisecond(struct timespec *target, long long ms)
{
time_t sec = ms / MILLISECONDS_IN_SECOND;
if (ms < 0) {
sec -= 1;
}
ms -= sec * MILLISECONDS_IN_SECOND;
target->tv_sec = sec;
target->tv_nsec = ms * (NANOSECONDS_IN_SECOND / MILLISECONDS_IN_SECOND);
}
__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_from_nanosecond(long long ns)
{
RelativeTime result;
timespec_assign_nanosecond(&result.relative, ns);
return result;
}
__attribute__((unused)) inline static RelativeTime
relative_time_from_millisecond(long long ms)
{
RelativeTime result;
timespec_assign_millisecond(&result.relative, ms);
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_ */