1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2025 Oxide Computer Company 14 */ 15 16 /* 17 * Basic tests for C23 timespec_getres. 18 */ 19 20 #include <stdlib.h> 21 #include <time.h> 22 #include <err.h> 23 #include <sys/sysmacros.h> 24 #include <limits.h> 25 26 typedef struct { 27 int rc_base; 28 clockid_t rc_clock; 29 const char *rc_desc; 30 } res_cmp_t; 31 32 static const res_cmp_t resolutions[] = { 33 { TIME_UTC, CLOCK_REALTIME, "real time clock" }, 34 { TIME_MONOTONIC, CLOCK_HIGHRES, "highres clock" }, 35 { TIME_ACTIVE, CLOCK_PROCESS_CPUTIME_ID, "process clock" }, 36 { TIME_THREAD_ACTIVE, CLOCK_THREAD_CPUTIME_ID, "thread clock" }, 37 { TIME_THREAD_ACTIVE_USR, CLOCK_VIRTUAL, "thread (usr) clock" }, 38 }; 39 40 static const int bad_clocks[] = { 23, INT_MAX, INT_MIN, -42 }; 41 42 int 43 main(void) 44 { 45 int ret = EXIT_SUCCESS; 46 for (size_t i = 0; i < ARRAY_SIZE(resolutions); i++) { 47 struct timespec ts_c, ts_posix; 48 int res; 49 50 res = timespec_getres(&ts_c, resolutions[i].rc_base); 51 if (res != resolutions[i].rc_base) { 52 warnx("TEST FAILED: %s: timespec_getres did not " 53 "return expected base %d, got %d", 54 resolutions[i].rc_desc, resolutions[i].rc_base, 55 res); 56 ret = EXIT_FAILURE; 57 continue; 58 } 59 60 if (clock_getres(resolutions[i].rc_clock, &ts_posix) != 0) { 61 warn("TEST FAILED: %s: clock_getres for clock %d " 62 "failed", resolutions[i].rc_desc, 63 resolutions[i].rc_clock); 64 ret = EXIT_FAILURE; 65 continue; 66 } 67 68 if (ts_c.tv_sec != ts_posix.tv_sec || 69 ts_c.tv_nsec != ts_posix.tv_nsec) { 70 warnx("TEST FAILED: %s: resolution mismatch: C has " 71 "0x%lx/0x%lx, posix has 0x%lx/0x%lx", 72 resolutions[i].rc_desc, ts_c.tv_sec, ts_c.tv_nsec, 73 ts_posix.tv_sec, ts_posix.tv_nsec); 74 ret = EXIT_FAILURE; 75 continue; 76 } 77 78 (void) printf("TEST PASSED: %s: C and POSIX resoultions " 79 "match\n", resolutions[i].rc_desc); 80 } 81 82 for (size_t i = 0; i < ARRAY_SIZE(bad_clocks); i++) { 83 struct timespec ts; 84 85 if (timespec_getres(&ts, bad_clocks[i]) != 0) { 86 warnx("TEST FAILED: timespec_getres didn't fail " 87 "with bad clock (%d)", bad_clocks[i]); 88 ret = EXIT_FAILURE; 89 } else { 90 (void) printf("TEST PASSED: timespec_getres failed " 91 "with bad clock (%d)\n", bad_clocks[i]); 92 } 93 } 94 95 if (ret == EXIT_SUCCESS) { 96 (void) printf("All tests passed successfully\n"); 97 } 98 99 return (ret); 100 } 101