1 /*
2 * Copyright (c) 2018 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <ztest.h>
8 #include <errno.h>
9 #include <posix/time.h>
10 #include <stdint.h>
11 #include <sys_clock.h>
12
13 /** req and rem are both NULL */
test_nanosleep_NULL_NULL(void)14 void test_nanosleep_NULL_NULL(void)
15 {
16 int r = nanosleep(NULL, NULL);
17
18 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
19 zassert_equal(errno, EFAULT, "actual: %d expected: %d", errno, EFAULT);
20 }
21
22 /**
23 * req is NULL, rem is non-NULL (all-zero)
24 *
25 * Expect rem to be the same when function returns
26 */
test_nanosleep_NULL_notNULL(void)27 void test_nanosleep_NULL_notNULL(void)
28 {
29 struct timespec rem = {};
30
31 errno = 0;
32 int r = nanosleep(NULL, &rem);
33
34 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
35 zassert_equal(errno, EFAULT, "actual: %d expected: %d",
36 errno, EFAULT);
37 zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
38 rem.tv_sec, 0);
39 zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
40 rem.tv_nsec, 0);
41 }
42
43 /**
44 * req is non-NULL (all-zero), rem is NULL
45 *
46 * Expect req to be the same when function returns
47 */
test_nanosleep_notNULL_NULL(void)48 void test_nanosleep_notNULL_NULL(void)
49 {
50 struct timespec req = {};
51
52 errno = 0;
53 int r = nanosleep(&req, NULL);
54
55 zassert_equal(req.tv_sec, 0, "actual: %d expected: %d",
56 req.tv_sec, 0);
57 zassert_equal(req.tv_nsec, 0, "actual: %d expected: %d",
58 req.tv_nsec, 0);
59 zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
60 zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
61 }
62
63 /**
64 * req is non-NULL (all-zero), rem is non-NULL (all-zero)
65 *
66 * Expect req & rem to be the same when function returns
67 */
test_nanosleep_notNULL_notNULL(void)68 void test_nanosleep_notNULL_notNULL(void)
69 {
70 struct timespec req = {};
71 struct timespec rem = {};
72
73 errno = 0;
74 int r = nanosleep(&req, &rem);
75
76 zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
77 zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
78 zassert_equal(req.tv_sec, 0, "actual: %d expected: %d",
79 req.tv_sec, 0);
80 zassert_equal(req.tv_nsec, 0, "actual: %d expected: %d",
81 req.tv_nsec, 0);
82 zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
83 rem.tv_sec, 0);
84 zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
85 rem.tv_nsec, 0);
86 }
87
88 /**
89 * req and rem point to the same timespec
90 *
91 * Normative spec says they may be the same.
92 * Expect rem to be zero after returning.
93 */
test_nanosleep_req_is_rem(void)94 void test_nanosleep_req_is_rem(void)
95 {
96 struct timespec ts = {0, 1};
97
98 errno = 0;
99 int r = nanosleep(&ts, &ts);
100
101 zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
102 zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
103 zassert_equal(ts.tv_sec, 0, "actual: %d expected: %d",
104 ts.tv_sec, 0);
105 zassert_equal(ts.tv_nsec, 0, "actual: %d expected: %d",
106 ts.tv_nsec, 0);
107 }
108
109 /** req tv_sec is -1 */
test_nanosleep_n1_0(void)110 void test_nanosleep_n1_0(void)
111 {
112 struct timespec req = {-1, 0};
113
114 errno = 0;
115 int r = nanosleep(&req, NULL);
116
117 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
118 zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
119 }
120
121 /** req tv_nsec is -1 */
test_nanosleep_0_n1(void)122 void test_nanosleep_0_n1(void)
123 {
124 struct timespec req = {0, -1};
125
126 errno = 0;
127 int r = nanosleep(&req, NULL);
128
129 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
130 zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
131 }
132
133 /** req tv_sec and tv_nsec are both -1 */
test_nanosleep_n1_n1(void)134 void test_nanosleep_n1_n1(void)
135 {
136 struct timespec req = {-1, -1};
137
138 errno = 0;
139 int r = nanosleep(&req, NULL);
140
141 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
142 zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
143 }
144
145 /** req tv_sec is 0 tv_nsec is 10^9 */
test_nanosleep_0_1000000000(void)146 void test_nanosleep_0_1000000000(void)
147 {
148 struct timespec req = {0, 1000000000};
149
150 errno = 0;
151 int r = nanosleep(&req, NULL);
152
153 zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
154 zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
155 }
156
common(const uint32_t s,uint32_t ns)157 static void common(const uint32_t s, uint32_t ns)
158 {
159 uint32_t then;
160 uint32_t now;
161 int r;
162 struct timespec req = {s, ns};
163 struct timespec rem = {0, 0};
164
165 errno = 0;
166 then = k_cycle_get_32();
167 r = nanosleep(&req, &rem);
168 now = k_cycle_get_32();
169
170 zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
171 zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
172 zassert_equal(req.tv_sec, s, "actual: %d expected: %d",
173 req.tv_sec, s);
174 zassert_equal(req.tv_nsec, ns, "actual: %d expected: %d",
175 req.tv_nsec, ns);
176 zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
177 rem.tv_sec, 0);
178 zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
179 rem.tv_nsec, 0);
180
181 uint64_t actual_ns = k_cyc_to_ns_ceil64((now - then));
182 uint64_t exp_ns = (uint64_t)s * NSEC_PER_SEC + ns;
183 /* round up to the nearest microsecond for k_busy_wait() */
184 exp_ns = ceiling_fraction(exp_ns, NSEC_PER_USEC) * NSEC_PER_USEC;
185
186 /* lower bounds check */
187 zassert_true(actual_ns >= exp_ns,
188 "actual: %llu expected: %llu", actual_ns, exp_ns);
189
190 /* TODO: Upper bounds check when hr timers are available */
191 }
192
193 /** sleep for 1ns */
test_nanosleep_0_1(void)194 void test_nanosleep_0_1(void)
195 {
196 common(0, 1);
197 }
198
199 /** sleep for 1us + 1ns */
test_nanosleep_0_1001(void)200 void test_nanosleep_0_1001(void)
201 {
202 common(0, 1001);
203 }
204
205 /** sleep for 500000000ns */
test_nanosleep_0_500000000(void)206 void test_nanosleep_0_500000000(void)
207 {
208 common(0, 500000000);
209 }
210
211 /** sleep for 1s */
test_nanosleep_1_0(void)212 void test_nanosleep_1_0(void)
213 {
214 common(1, 0);
215 }
216
217 /** sleep for 1s + 1ns */
test_nanosleep_1_1(void)218 void test_nanosleep_1_1(void)
219 {
220 common(1, 1);
221 }
222
223 /** sleep for 1s + 1us + 1ns */
test_nanosleep_1_1001(void)224 void test_nanosleep_1_1001(void)
225 {
226 common(1, 1001);
227 }
228