diff options
Diffstat (limited to 'hrtime.h')
-rw-r--r-- | hrtime.h | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -36,6 +36,7 @@ #define RB_HRTIME_PER_MSEC (RB_HRTIME_PER_USEC * (rb_hrtime_t)1000) #define RB_HRTIME_PER_SEC (RB_HRTIME_PER_MSEC * (rb_hrtime_t)1000) #define RB_HRTIME_MAX UINT64_MAX +#define RB_HRTIME_MIN ((rb_hrtime_t)0) /* * Lets try to support time travelers. Lets assume anybody with a time machine @@ -91,6 +92,15 @@ rb_hrtime_add(rb_hrtime_t a, rb_hrtime_t b) return c; } +static inline rb_hrtime_t +rb_hrtime_sub(rb_hrtime_t a, rb_hrtime_t b) +{ + if (a < b) { + return RB_HRTIME_MIN; + } + return a - b; +} + /* * convert a timeval struct to rb_hrtime_t, clamping at RB_HRTIME_MAX */ @@ -165,4 +175,53 @@ rb_hrtime2timeval(struct timeval *tv, const rb_hrtime_t *hrt) } return 0; } + +#include "internal/warnings.h" +#include "internal/time.h" + +/* + * Back when we used "struct timeval", not all platforms implemented + * tv_sec as time_t. Nowadays we use "struct timespec" and tv_sec + * seems to be implemented more consistently across platforms. + * At least other parts of our code hasn't had to deal with non-time_t + * tv_sec in timespec... + */ +#define TIMESPEC_SEC_MAX TIMET_MAX +#define TIMESPEC_SEC_MIN TIMET_MIN + +COMPILER_WARNING_PUSH +#if __has_warning("-Wimplicit-int-float-conversion") +COMPILER_WARNING_IGNORED(-Wimplicit-int-float-conversion) +#elif defined(_MSC_VER) +/* C4305: 'initializing': truncation from '__int64' to 'const double' */ +COMPILER_WARNING_IGNORED(4305) +#endif +static const double TIMESPEC_SEC_MAX_as_double = TIMESPEC_SEC_MAX; +COMPILER_WARNING_POP + +static inline rb_hrtime_t * +double2hrtime(rb_hrtime_t *hrt, double d) +{ + /* assume timespec.tv_sec has same signedness as time_t */ + const double TIMESPEC_SEC_MAX_PLUS_ONE = 2.0 * (TIMESPEC_SEC_MAX_as_double / 2.0 + 1.0); + + if (TIMESPEC_SEC_MAX_PLUS_ONE <= d) { + *hrt = RB_HRTIME_MAX; + return NULL; + } + else if (d <= 0) { + *hrt = 0; + } + else { + *hrt = (rb_hrtime_t)(d * (double)RB_HRTIME_PER_SEC); + } + return hrt; +} + +static inline double +hrtime2double(rb_hrtime_t hrt) +{ + return (double)hrt / (double)RB_HRTIME_PER_SEC; +} + #endif /* RB_HRTIME_H */ |