--- Gnu-Mach/include/mach/time_value.h 2020/09/02 04:36:57 1.1.1.1 +++ Gnu-Mach/include/mach/time_value.h 2020/09/02 04:50:22 1.1.1.2 @@ -45,29 +45,48 @@ typedef struct time_value time_value_t; */ #define TIME_MICROS_MAX (1000000) +#define time_value_assert(val) \ + assert(0 <= (val)->microseconds && (val)->microseconds < TIME_MICROS_MAX); + #define time_value_add_usec(val, micros) { \ + time_value_assert(val); \ if (((val)->microseconds += (micros)) \ >= TIME_MICROS_MAX) { \ (val)->microseconds -= TIME_MICROS_MAX; \ (val)->seconds++; \ } \ + time_value_assert(val); \ } -#define time_value_add(result, addend) { \ - (result)->microseconds += (addend)->microseconds; \ - (result)->seconds += (addend)->seconds; \ - if ((result)->microseconds >= TIME_MICROS_MAX) { \ - (result)->microseconds -= TIME_MICROS_MAX; \ - (result)->seconds++; \ - } \ +#define time_value_sub_usec(val, micros) { \ + time_value_assert(val); \ + if (((val)->microseconds -= (micros)) < 0) { \ + (val)->microseconds += TIME_MICROS_MAX; \ + (val)->seconds--; \ + } \ + time_value_assert(val); \ } +#define time_value_add(result, addend) { \ + time_value_assert(addend); \ + (result)->seconds += (addend)->seconds; \ + time_value_add_usec(result, (addend)->microseconds); \ + } + +#define time_value_sub(result, subtrahend) { \ + time_value_assert(subtrahend); \ + (result)->seconds -= (subtrahend)->seconds; \ + time_value_sub_usec(result, (subtrahend)->microseconds); \ + } + /* * Time value available through the mapped-time interface. * Read this mapped value with * do { * secs = mtime->seconds; + * __sync_synchronize(); * usecs = mtime->microseconds; + * __sync_synchronize(); * } while (secs != mtime->check_seconds); */ @@ -77,4 +96,16 @@ typedef struct mapped_time_value { integer_t check_seconds; } mapped_time_value_t; +/* Macros for converting between struct timespec and time_value_t. */ + +#define TIME_VALUE_TO_TIMESPEC(tv, ts) do { \ + (ts)->tv_sec = (tv)->seconds; \ + (ts)->tv_nsec = (tv)->microseconds * 1000; \ +} while(0) + +#define TIMESPEC_TO_TIME_VALUE(tv, ts) do { \ + (tv)->seconds = (ts)->tv_sec; \ + (tv)->microseconds = (ts)->tv_nsec / 1000; \ +} while(0) + #endif /* _MACH_TIME_VALUE_H_ */