Skip to content

Commit

Permalink
timeutil: add a minimum support of monotonic clock
Browse files Browse the repository at this point in the history
  • Loading branch information
yamt committed Feb 1, 2023
1 parent dc896e9 commit 4bbf494
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 17 deletions.
54 changes: 46 additions & 8 deletions lib/timeutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ timespec_from_ns(struct timespec *a, uint64_t ns)
}

int
timespec_now(struct timespec *a)
timespec_now(clockid_t id, struct timespec *a)
{
int ret = clock_gettime(CLOCK_REALTIME, a);
int ret = clock_gettime(id, a);
if (ret != 0) {
assert(errno != 0);
return errno;
Expand All @@ -114,7 +114,8 @@ timespec_now(struct timespec *a)
}

int
abstime_from_reltime_ns(struct timespec *abstime, uint64_t reltime_ns)
abstime_from_reltime_ns(clockid_t id, struct timespec *abstime,
uint64_t reltime_ns)
{
struct timespec now;
struct timespec reltime;
Expand All @@ -123,7 +124,7 @@ abstime_from_reltime_ns(struct timespec *abstime, uint64_t reltime_ns)
if (ret != 0) {
goto fail;
}
ret = timespec_now(&now);
ret = timespec_now(id, &now);
if (ret != 0) {
goto fail;
}
Expand All @@ -135,19 +136,20 @@ abstime_from_reltime_ns(struct timespec *abstime, uint64_t reltime_ns)
return ret;
}
int
abstime_from_reltime_ms(struct timespec *abstime, int reltime_ms)
abstime_from_reltime_ms(clockid_t id, struct timespec *abstime, int reltime_ms)
{
return abstime_from_reltime_ns(abstime,
return abstime_from_reltime_ns(id, abstime,
(uint64_t)reltime_ms * 1000000);
}

int
abstime_to_reltime_ms_roundup(const struct timespec *abstime, int *reltime_ms)
abstime_to_reltime_ms_roundup(clockid_t id, const struct timespec *abstime,
int *reltime_ms)
{
struct timespec now;
struct timespec reltime;
int ret;
ret = timespec_now(&now);
ret = timespec_now(id, &now);
if (ret != 0) {
goto fail;
}
Expand All @@ -174,3 +176,39 @@ abstime_to_reltime_ms_roundup(const struct timespec *abstime, int *reltime_ms)
fail:
return ret;
}

int
convert_timespec(clockid_t from_id, clockid_t to_id,
const struct timespec *from_ts, struct timespec *result)
{
struct timespec from_now;
struct timespec to_now;
int ret;
ret = timespec_now(from_id, &from_now);
if (ret != 0) {
goto fail;
}
ret = timespec_now(to_id, &to_now);
if (ret != 0) {
goto fail;
}
if (timespec_cmp(from_ts, &from_now) >= 0) {
struct timespec t;
timespec_sub(from_ts, &from_now, &t);
ret = timespec_add(&t, &to_now, result);
if (ret != 0) {
goto fail;
}
} else {
struct timespec t;
timespec_sub(&from_now, from_ts, &t);
if (timespec_cmp(&to_now, &t) > 0) {
ret = EOVERFLOW;
goto fail;
}
timespec_sub(&to_now, &t, result);
}
return 0;
fail:
return ret;
}
13 changes: 9 additions & 4 deletions lib/timeutil.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdint.h>
#include <time.h>

struct timespec;

Expand All @@ -8,10 +9,14 @@ int timespec_add(const struct timespec *a, const struct timespec *b,
void timespec_sub(const struct timespec *a, const struct timespec *b,
struct timespec *c);
int timespec_from_ns(struct timespec *a, uint64_t ns);
int timespec_now(struct timespec *a);
int timespec_now(clockid_t id, struct timespec *a);

int abstime_from_reltime_ns(struct timespec *abstime, uint64_t reltime_ns);
int abstime_from_reltime_ns(clockid_t id, struct timespec *abstime,
uint64_t reltime_ns);

int abstime_from_reltime_ms(struct timespec *abstime, int reltime_ms);
int abstime_to_reltime_ms_roundup(const struct timespec *abstime,
int abstime_from_reltime_ms(clockid_t id, struct timespec *abstime,
int reltime_ms);
int abstime_to_reltime_ms_roundup(clockid_t id, const struct timespec *abstime,
int *reltime_ms);
int convert_timespec(clockid_t from_id, clockid_t to_id,
const struct timespec *from_ts, struct timespec *result);
9 changes: 6 additions & 3 deletions lib/wasi.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds,
if (timeout_ms < 0) {
abstimeout = NULL;
} else {
ret = abstime_from_reltime_ms(&abstimeout0, timeout_ms);
ret = abstime_from_reltime_ms(CLOCK_REALTIME, &abstimeout0,
timeout_ms);
if (ret != 0) {
goto fail;
}
Expand All @@ -895,15 +896,17 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds,
next_timeout_ms = interval_ms;
} else {
struct timespec next;
ret = abstime_from_reltime_ms(&next, interval_ms);
ret = abstime_from_reltime_ms(CLOCK_REALTIME, &next,
interval_ms);
if (ret != 0) {
goto fail;
}
if (timespec_cmp(abstimeout, &next) > 0) {
next_timeout_ms = interval_ms;
} else {
ret = abstime_to_reltime_ms_roundup(
abstimeout, &next_timeout_ms);
CLOCK_REALTIME, abstimeout,
&next_timeout_ms);
if (ret != 0) {
goto fail;
}
Expand Down
4 changes: 2 additions & 2 deletions test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,9 @@ test_timeutil(void **state)
struct timespec c;
int ret;

ret = timespec_now(&a);
ret = timespec_now(CLOCK_REALTIME, &a);
assert_int_equal(ret, 0);
ret = timespec_now(&b);
ret = timespec_now(CLOCK_REALTIME, &b);
assert_int_equal(ret, 0);
ret = timespec_cmp(&a, &b);
assert_true(ret <= 0);
Expand Down

0 comments on commit 4bbf494

Please sign in to comment.