1 // Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
3 // SPDX-License-Identifier: BSD-2-Clause
8 #include <common/limits.h>
16 #define NSEC_PER_SEC 1000000000
18 static inline bool timespec_to_timestamp_exact(
19 const struct timespec
*timespec
, __wasi_timestamp_t
*timestamp
) {
20 // Invalid nanoseconds field.
21 if (timespec
->tv_nsec
< 0 || timespec
->tv_nsec
>= NSEC_PER_SEC
)
24 // Timestamps before the Epoch are not supported.
25 if (timespec
->tv_sec
< 0)
28 // Make sure our timestamp does not overflow.
29 return !__builtin_mul_overflow(timespec
->tv_sec
, NSEC_PER_SEC
, timestamp
) &&
30 !__builtin_add_overflow(*timestamp
, timespec
->tv_nsec
, timestamp
);
33 static inline bool timespec_to_timestamp_clamp(
34 const struct timespec
*timespec
, __wasi_timestamp_t
*timestamp
) {
35 // Invalid nanoseconds field.
36 if (timespec
->tv_nsec
< 0 || timespec
->tv_nsec
>= NSEC_PER_SEC
)
39 if (timespec
->tv_sec
< 0) {
40 // Timestamps before the Epoch are not supported.
42 } else if (__builtin_mul_overflow(timespec
->tv_sec
, NSEC_PER_SEC
, timestamp
) ||
43 __builtin_add_overflow(*timestamp
, timespec
->tv_nsec
, timestamp
)) {
44 // Make sure our timestamp does not overflow.
45 *timestamp
= NUMERIC_MAX(__wasi_timestamp_t
);
50 static inline struct timespec
timestamp_to_timespec(
51 __wasi_timestamp_t timestamp
) {
52 // Decompose timestamp into seconds and nanoseconds.
53 return (struct timespec
){.tv_sec
= timestamp
/ NSEC_PER_SEC
,
54 .tv_nsec
= timestamp
% NSEC_PER_SEC
};
57 static inline struct timeval
timestamp_to_timeval(
58 __wasi_timestamp_t timestamp
) {
59 struct timespec ts
= timestamp_to_timespec(timestamp
);
60 return (struct timeval
){.tv_sec
= ts
.tv_sec
, ts
.tv_nsec
/ 1000};