Fix handling of overflow and non-canonical values in timespec APIs.

Support zero relative and absolute times in the timer API.
This commit is contained in:
Jonas 'Sortie' Termansen 2021-06-20 22:44:19 +02:00
parent 109a229b42
commit 4daedc31f7
10 changed files with 125 additions and 36 deletions
libc/include

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
* Copyright (c) 2013, 2021 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -28,25 +28,22 @@
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __time_t_defined
#define __time_t_defined
typedef __time_t time_t;
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#include <sortix/timespec.h>
#ifdef __cplusplus
extern "C" {
#endif
static __inline bool timespec_is_canonical(struct timespec t)
{
return 0 <= t.tv_nsec && t.tv_nsec <= 999999999;
}
static __inline bool timespec_eq(struct timespec a, struct timespec b)
{
return a.tv_sec == b.tv_sec && a.tv_nsec == b.tv_nsec;
@ -91,6 +88,9 @@ static __inline struct timespec timespec_make(time_t sec, long nsec)
static __inline struct timespec timespec_neg(struct timespec t)
{
if ( t.tv_sec == __TIME_MIN )
return timespec_make(__TIME_MAX,
!t.tv_nsec ? 999999999 : 1000000000 - t.tv_nsec);
if ( t.tv_nsec )
return timespec_make(-t.tv_sec - 1, 1000000000 - t.tv_nsec);
return timespec_make(-t.tv_sec, 0);
@ -101,9 +101,11 @@ static __inline struct timespec timespec_nul(void)
return timespec_make(0, 0);
}
struct timespec timespec_canonalize(struct timespec t);
struct timespec timespec_add(struct timespec a, struct timespec b);
struct timespec timespec_sub(struct timespec a, struct timespec b);
struct timespec timespec_canonalize(struct timespec);
struct timespec timespec_add(struct timespec, struct timespec);
struct timespec timespec_sub(struct timespec, struct timespec);
bool timespec_add_overflow(struct timespec, struct timespec, struct timespec*);
bool timespec_sub_overflow(struct timespec, struct timespec, struct timespec*);
#ifdef __cplusplus
} /* extern "C" */