/* SPDX-License-Identifier: LGPL-2.1-only */ /* * The Rin Library – time module * * Copyright (C) 2017-2019 Gediminas Jakutis */ #include "rin/time.h" #include "time_private.h" struct timespec rin_time_add(const struct timespec * const a, const struct timespec * const b) { struct timespec ret; ret.tv_sec = a->tv_sec + b->tv_sec; ret.tv_nsec = a->tv_nsec + b->tv_nsec; return rin_time_normalize(&ret); } struct timespec rin_time_sub(const struct timespec * const a, const struct timespec * const b) { struct timespec ret; ret.tv_sec = a->tv_sec - b->tv_sec; ret.tv_nsec = a->tv_nsec - b->tv_nsec; return rin_time_normalize(&ret); } struct timespec rin_time_normalize(const struct timespec * const t) { struct timespec ret; ret = *t; if (ret.tv_nsec >= 0 && ret.tv_nsec <= tv_nsec_max) { return ret; } if (ret.tv_nsec > 0) { ret.tv_sec += ret.tv_nsec / (tv_nsec_max + 1); ret.tv_nsec = ret.tv_nsec % (tv_nsec_max + 1); } else { ret.tv_sec += ret.tv_nsec / (tv_nsec_max + 1) - 1; ret.tv_nsec = (tv_nsec_max + 1) - (-ret.tv_nsec) % (tv_nsec_max + 1); } return ret; } struct timeval rin_timeval_add(const struct timeval * const a, const struct timeval * const b) { struct timeval ret; ret.tv_sec = a->tv_sec + b->tv_sec; ret.tv_usec = a->tv_usec + b->tv_usec; return rin_timeval_normalize(&ret); } struct timeval rin_timeval_sub(const struct timeval * const a, const struct timeval * const b) { struct timeval ret; ret.tv_sec = a->tv_sec - b->tv_sec; ret.tv_usec = a->tv_usec - b->tv_usec; return rin_timeval_normalize(&ret); } struct timeval rin_timeval_normalize(const struct timeval * const t) { struct timeval ret; ret = *t; if (ret.tv_usec >= 0 && ret.tv_usec <= tv_usec_max) { return ret; } if (ret.tv_usec > 0) { ret.tv_sec += ret.tv_usec / (tv_usec_max + 1); ret.tv_usec = ret.tv_usec % (tv_usec_max + 1); } else { ret.tv_sec += ret.tv_usec / (tv_usec_max + 1) - 1; ret.tv_usec = (tv_usec_max + 1) - (-ret.tv_usec) % (tv_usec_max + 1); } return ret; } long int rin_time_cmp(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec != b->tv_sec) { return a->tv_sec - b->tv_sec; } else { return a->tv_nsec - b->tv_nsec; } } long int rin_timeval_cmp(const struct timeval * const a, const struct timeval * const b) { if (a->tv_sec != b->tv_sec) { return a->tv_sec - b->tv_sec; } else { return a->tv_usec - b->tv_usec; } } unsigned int rin_time_cmp_less(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec > b->tv_sec) { return 0; } else if (a->tv_sec < b->tv_sec) { return 1; } else { return a->tv_nsec < b->tv_nsec; } } unsigned int rin_time_cmp_more(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec < b->tv_sec) { return 0; } else if (a->tv_sec > b->tv_sec) { return 1; } else { return a->tv_nsec > b->tv_nsec; } } unsigned int rin_time_cmp_lessequal(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec > b->tv_sec) { return 0; } else if (a->tv_sec < b->tv_sec) { return 1; } else { return a->tv_nsec <= b->tv_nsec; } } unsigned int rin_time_cmp_moreequal(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec < b->tv_sec) { return 0; } else if (a->tv_sec > b->tv_sec) { return 1; } else { return a->tv_nsec >= b->tv_nsec; } } unsigned int rin_time_cmp_equal(const struct timespec * const a, const struct timespec * const b) { return a->tv_sec == b->tv_sec && a->tv_nsec == b->tv_nsec; } unsigned int rin_time_cmp_nonequal(const struct timespec * const a, const struct timespec * const b) { return a->tv_sec != b->tv_sec || a->tv_nsec != b->tv_nsec; } unsigned int rin_timeval_cmp_less(const struct timeval * const a, const struct timeval * const b) { if (a->tv_sec > b->tv_sec) { return 0; } else if (a->tv_sec < b->tv_sec) { return 1; } else { return a->tv_usec < b->tv_usec; } } unsigned int rin_timeval_cmp_more(const struct timeval * const a, const struct timeval * const b) { if (a->tv_sec < b->tv_sec) { return 0; } else if (a->tv_sec > b->tv_sec) { return 1; } else { return a->tv_usec > b->tv_usec; } } unsigned int rin_timeval_cmp_lessequal(const struct timeval * const a, const struct timeval * const b) { if (a->tv_sec > b->tv_sec) { return 0; } else if (a->tv_sec < b->tv_sec) { return 1; } else { return a->tv_usec <= b->tv_usec; } } unsigned int rin_timeval_cmp_moreequal(const struct timeval * const a, const struct timeval * const b) { if (a->tv_sec < b->tv_sec) { return 0; } else if (a->tv_sec > b->tv_sec) { return 1; } else { return a->tv_usec >= b->tv_usec; } } unsigned int rin_timeval_cmp_equal(const struct timeval * const a, const struct timeval * const b) { return a->tv_sec == b->tv_sec && a->tv_usec == b->tv_usec; } unsigned int rin_timeval_cmp_nonequal(const struct timeval * const a, const struct timeval * const b) { return a->tv_sec != b->tv_sec || a->tv_usec != b->tv_usec; }