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
main(void)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