t_timer_create.c revision 1.6 1 1.6 riastrad /* $NetBSD: t_timer_create.c,v 1.6 2024/12/18 22:26:53 riastradh Exp $ */
2 1.1 jruoho
3 1.1 jruoho /*-
4 1.1 jruoho * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1 jruoho * All rights reserved.
6 1.1 jruoho *
7 1.1 jruoho * Redistribution and use in source and binary forms, with or without
8 1.1 jruoho * modification, are permitted provided that the following conditions
9 1.1 jruoho * are met:
10 1.1 jruoho * 1. Redistributions of source code must retain the above copyright
11 1.1 jruoho * notice, this list of conditions and the following disclaimer.
12 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jruoho * notice, this list of conditions and the following disclaimer in the
14 1.1 jruoho * documentation and/or other materials provided with the distribution.
15 1.1 jruoho *
16 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE.
27 1.1 jruoho */
28 1.1 jruoho
29 1.2 jruoho #include <atf-c.h>
30 1.1 jruoho #include <errno.h>
31 1.2 jruoho #include <stdio.h>
32 1.1 jruoho #include <signal.h>
33 1.1 jruoho #include <string.h>
34 1.1 jruoho #include <time.h>
35 1.1 jruoho #include <unistd.h>
36 1.1 jruoho
37 1.6 riastrad #include "h_macros.h"
38 1.6 riastrad
39 1.2 jruoho static timer_t t;
40 1.6 riastrad static sig_atomic_t expired;
41 1.6 riastrad
42 1.6 riastrad enum mode {
43 1.6 riastrad PAST,
44 1.6 riastrad EXPIRE,
45 1.6 riastrad NOEXPIRE,
46 1.6 riastrad };
47 1.1 jruoho
48 1.2 jruoho static void
49 1.5 christos timer_signal_handler(int signo, siginfo_t *si, void *osi __unused)
50 1.1 jruoho {
51 1.2 jruoho timer_t *tp;
52 1.1 jruoho
53 1.2 jruoho tp = si->si_value.sival_ptr;
54 1.1 jruoho
55 1.2 jruoho if (*tp == t && signo == SIGALRM)
56 1.6 riastrad expired = 1;
57 1.1 jruoho
58 1.2 jruoho (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo));
59 1.1 jruoho }
60 1.1 jruoho
61 1.1 jruoho static void
62 1.6 riastrad timer_signal_create(clockid_t cid, enum mode mode, int flags)
63 1.1 jruoho {
64 1.6 riastrad struct itimerspec tim, rtim, otim;
65 1.6 riastrad struct timespec t0, t1, dt;
66 1.1 jruoho struct sigaction act;
67 1.1 jruoho struct sigevent evt;
68 1.1 jruoho sigset_t set;
69 1.1 jruoho
70 1.2 jruoho t = 0;
71 1.6 riastrad expired = 0;
72 1.1 jruoho
73 1.1 jruoho (void)memset(&evt, 0, sizeof(struct sigevent));
74 1.1 jruoho (void)memset(&act, 0, sizeof(struct sigaction));
75 1.1 jruoho (void)memset(&tim, 0, sizeof(struct itimerspec));
76 1.1 jruoho
77 1.2 jruoho /*
78 1.2 jruoho * Set handler.
79 1.2 jruoho */
80 1.1 jruoho act.sa_flags = SA_SIGINFO;
81 1.1 jruoho act.sa_sigaction = timer_signal_handler;
82 1.1 jruoho
83 1.2 jruoho ATF_REQUIRE(sigemptyset(&set) == 0);
84 1.2 jruoho ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0);
85 1.1 jruoho
86 1.2 jruoho /*
87 1.2 jruoho * Block SIGALRM while configuring the timer.
88 1.2 jruoho */
89 1.2 jruoho ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0);
90 1.2 jruoho ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0);
91 1.2 jruoho ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
92 1.2 jruoho
93 1.2 jruoho /*
94 1.2 jruoho * Create the timer (SIGEV_SIGNAL).
95 1.2 jruoho */
96 1.2 jruoho evt.sigev_signo = SIGALRM;
97 1.1 jruoho evt.sigev_value.sival_ptr = &t;
98 1.1 jruoho evt.sigev_notify = SIGEV_SIGNAL;
99 1.1 jruoho
100 1.2 jruoho ATF_REQUIRE(timer_create(cid, &evt, &t) == 0);
101 1.2 jruoho
102 1.2 jruoho /*
103 1.6 riastrad * Configure the timer for -1, 1, or 5 sec from now, depending
104 1.6 riastrad * on whether we want it to have fired, to fire within 2sec, or
105 1.6 riastrad * to not fire within 2sec.
106 1.2 jruoho */
107 1.6 riastrad switch (mode) {
108 1.6 riastrad case PAST:
109 1.6 riastrad tim.it_value.tv_sec = -1;
110 1.6 riastrad break;
111 1.6 riastrad case EXPIRE:
112 1.6 riastrad tim.it_value.tv_sec = 1;
113 1.6 riastrad break;
114 1.6 riastrad case NOEXPIRE:
115 1.6 riastrad tim.it_value.tv_sec = 5;
116 1.6 riastrad break;
117 1.6 riastrad }
118 1.2 jruoho tim.it_value.tv_nsec = 0;
119 1.2 jruoho
120 1.6 riastrad /*
121 1.6 riastrad * Save the relative time and adjust for absolute time of
122 1.6 riastrad * requested.
123 1.6 riastrad */
124 1.6 riastrad rtim = tim;
125 1.6 riastrad RL(clock_gettime(cid, &t0));
126 1.6 riastrad if (flags & TIMER_ABSTIME)
127 1.6 riastrad timespecadd(&t0, &tim.it_value, &tim.it_value);
128 1.6 riastrad
129 1.6 riastrad fprintf(stderr, "now is %lld sec %d nsec\n",
130 1.6 riastrad (long long)t0.tv_sec, (int)t0.tv_nsec);
131 1.6 riastrad fprintf(stderr, "expire at %lld sec %d nsec\n",
132 1.6 riastrad (long long)tim.it_value.tv_sec, (int)tim.it_value.tv_nsec);
133 1.6 riastrad if (mode == PAST && (flags & TIMER_ABSTIME) == 0) {
134 1.6 riastrad atf_tc_expect_fail("PR kern/58919:"
135 1.6 riastrad " timer_settime fails to trigger for past times");
136 1.6 riastrad }
137 1.6 riastrad RL(timer_settime(t, flags, &tim, NULL));
138 1.6 riastrad RL(timer_settime(t, flags, &tim, &otim));
139 1.6 riastrad if (mode == PAST && (flags & TIMER_ABSTIME) == 0) {
140 1.6 riastrad atf_tc_expect_pass();
141 1.6 riastrad }
142 1.6 riastrad
143 1.6 riastrad RL(clock_gettime(cid, &t1));
144 1.6 riastrad timespecsub(&t1, &t0, &dt);
145 1.6 riastrad fprintf(stderr, "%lld sec %d nsec elapsed\n",
146 1.6 riastrad (long long)dt.tv_sec, (int)dt.tv_nsec);
147 1.6 riastrad
148 1.6 riastrad /*
149 1.6 riastrad * Check to make sure the time remaining is at most the
150 1.6 riastrad * relative time we expected.
151 1.6 riastrad */
152 1.6 riastrad atf_tc_expect_fail("PR kern/58917:"
153 1.6 riastrad " timer_settime and timerfd_settime return"
154 1.6 riastrad " absolute time of next event");
155 1.6 riastrad ATF_CHECK_MSG(timespeccmp(&otim.it_value, &rtim.it_value, <=),
156 1.6 riastrad "time remaining %lld sec %d nsec,"
157 1.6 riastrad " expected at most %lld sec %d nsec",
158 1.6 riastrad (long long)otim.it_value.tv_sec, (int)otim.it_value.tv_nsec,
159 1.6 riastrad (long long)rtim.it_value.tv_sec, (int)rtim.it_value.tv_nsec);
160 1.6 riastrad atf_tc_expect_pass();
161 1.6 riastrad
162 1.6 riastrad /*
163 1.6 riastrad * Until we fix PR kern/58917, adjust it to be relative to the
164 1.6 riastrad * start time.
165 1.6 riastrad */
166 1.6 riastrad timespecsub(&otim.it_value, &t0, &otim.it_value);
167 1.6 riastrad fprintf(stderr, "adjust otim to %lld sec %d nsec\n",
168 1.6 riastrad (long long)otim.it_value.tv_sec, (int)otim.it_value.tv_nsec);
169 1.6 riastrad
170 1.6 riastrad #if 0
171 1.6 riastrad /*
172 1.6 riastrad * Check to make sure that the amount the time remaining has
173 1.6 riastrad * gone down is at most the time elapsed.
174 1.6 riastrad *
175 1.6 riastrad * XXX Currently the time returned by timer_settime is only
176 1.6 riastrad * good to the nearest kernel tick (typically 10ms or 1ms), not
177 1.6 riastrad * to the resolution of the underlying clock -- unlike
178 1.6 riastrad * clock_gettime. So we can't set this bound. Not sure
179 1.6 riastrad * whether this is a bug or not, hence #if 0 instead of
180 1.6 riastrad * atf_tc_expect_fail.
181 1.6 riastrad */
182 1.6 riastrad timespecsub(&t1, &t0, &dt);
183 1.6 riastrad timespecsub(&rtim.it_value, &otim.it_value, &rtim.it_value);
184 1.6 riastrad ATF_CHECK_MSG(timespeccmp(&rtim.it_value, &dt, <=),
185 1.6 riastrad "time remaining went down by %lld sec %d nsec,"
186 1.6 riastrad " expected at most %lld sec %d nsec",
187 1.6 riastrad (long long)rtim.it_value.tv_sec, (int)rtim.it_value.tv_nsec,
188 1.6 riastrad (long long)dt.tv_sec, (int)dt.tv_nsec);
189 1.6 riastrad #endif
190 1.6 riastrad
191 1.6 riastrad /*
192 1.6 riastrad * Check to make sure the reload interval is what we set.
193 1.6 riastrad */
194 1.6 riastrad ATF_CHECK_MSG(timespeccmp(&otim.it_interval, &rtim.it_interval, ==),
195 1.6 riastrad "interval %lld sec %d nsec,"
196 1.6 riastrad " expected %lld sec %d nsec",
197 1.6 riastrad (long long)otim.it_interval.tv_sec, (int)otim.it_interval.tv_nsec,
198 1.6 riastrad (long long)rtim.it_interval.tv_sec, (int)rtim.it_interval.tv_nsec);
199 1.1 jruoho
200 1.2 jruoho (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
201 1.6 riastrad switch (mode) {
202 1.6 riastrad case PAST:
203 1.6 riastrad if (flags & TIMER_ABSTIME) {
204 1.6 riastrad atf_tc_expect_fail("PR kern/58919:"
205 1.6 riastrad " timer_settime fails to trigger for past times");
206 1.6 riastrad }
207 1.6 riastrad ATF_CHECK_MSG(expired, "timer failed to fire immediately");
208 1.6 riastrad if (flags & TIMER_ABSTIME) {
209 1.6 riastrad atf_tc_expect_pass();
210 1.6 riastrad }
211 1.6 riastrad break;
212 1.6 riastrad case EXPIRE:
213 1.6 riastrad case NOEXPIRE:
214 1.6 riastrad ATF_CHECK_MSG(!expired, "timer fired too soon");
215 1.6 riastrad (void)sleep(2);
216 1.6 riastrad switch (mode) {
217 1.6 riastrad case PAST:
218 1.6 riastrad __unreachable();
219 1.6 riastrad case EXPIRE:
220 1.6 riastrad ATF_CHECK_MSG(expired,
221 1.6 riastrad "timer failed to fire immediately");
222 1.6 riastrad break;
223 1.6 riastrad case NOEXPIRE:
224 1.6 riastrad ATF_CHECK_MSG(!expired, "timer fired too soon");
225 1.6 riastrad break;
226 1.6 riastrad }
227 1.6 riastrad break;
228 1.3 christos }
229 1.3 christos
230 1.3 christos ATF_REQUIRE(timer_delete(t) == 0);
231 1.1 jruoho }
232 1.1 jruoho
233 1.2 jruoho ATF_TC(timer_create_err);
234 1.2 jruoho ATF_TC_HEAD(timer_create_err, tc)
235 1.1 jruoho {
236 1.4 jruoho atf_tc_set_md_var(tc, "descr",
237 1.6 riastrad "Check errors from timer_create(2) (PR lib/42434)");
238 1.1 jruoho }
239 1.1 jruoho
240 1.2 jruoho ATF_TC_BODY(timer_create_err, tc)
241 1.1 jruoho {
242 1.2 jruoho struct sigevent ev;
243 1.1 jruoho
244 1.2 jruoho (void)memset(&ev, 0, sizeof(struct sigevent));
245 1.1 jruoho
246 1.1 jruoho errno = 0;
247 1.2 jruoho ev.sigev_signo = -1;
248 1.2 jruoho ev.sigev_notify = SIGEV_SIGNAL;
249 1.1 jruoho
250 1.2 jruoho ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
251 1.1 jruoho
252 1.2 jruoho errno = 0;
253 1.2 jruoho ev.sigev_signo = SIGUSR1;
254 1.2 jruoho ev.sigev_notify = SIGEV_THREAD + 100;
255 1.1 jruoho
256 1.2 jruoho ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
257 1.1 jruoho }
258 1.1 jruoho
259 1.2 jruoho ATF_TC(timer_create_real);
260 1.2 jruoho ATF_TC_HEAD(timer_create_real, tc)
261 1.1 jruoho {
262 1.1 jruoho
263 1.1 jruoho atf_tc_set_md_var(tc, "descr",
264 1.2 jruoho "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
265 1.2 jruoho "SIGEV_SIGNAL");
266 1.1 jruoho }
267 1.1 jruoho
268 1.2 jruoho ATF_TC_BODY(timer_create_real, tc)
269 1.1 jruoho {
270 1.6 riastrad timer_signal_create(CLOCK_REALTIME, NOEXPIRE, 0);
271 1.6 riastrad }
272 1.6 riastrad
273 1.6 riastrad ATF_TC(timer_create_real_abs);
274 1.6 riastrad ATF_TC_HEAD(timer_create_real_abs, tc)
275 1.6 riastrad {
276 1.6 riastrad
277 1.6 riastrad atf_tc_set_md_var(tc, "descr",
278 1.6 riastrad "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
279 1.6 riastrad "SIGEV_SIGNAL, using absolute time");
280 1.6 riastrad }
281 1.6 riastrad
282 1.6 riastrad ATF_TC_BODY(timer_create_real_abs, tc)
283 1.6 riastrad {
284 1.6 riastrad timer_signal_create(CLOCK_REALTIME, NOEXPIRE, TIMER_ABSTIME);
285 1.1 jruoho }
286 1.1 jruoho
287 1.2 jruoho ATF_TC(timer_create_mono);
288 1.2 jruoho ATF_TC_HEAD(timer_create_mono, tc)
289 1.1 jruoho {
290 1.1 jruoho
291 1.2 jruoho atf_tc_set_md_var(tc, "descr",
292 1.2 jruoho "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
293 1.2 jruoho "SIGEV_SIGNAL");
294 1.1 jruoho }
295 1.1 jruoho
296 1.2 jruoho ATF_TC_BODY(timer_create_mono, tc)
297 1.1 jruoho {
298 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, NOEXPIRE, 0);
299 1.6 riastrad }
300 1.6 riastrad
301 1.6 riastrad ATF_TC(timer_create_mono_abs);
302 1.6 riastrad ATF_TC_HEAD(timer_create_mono_abs, tc)
303 1.6 riastrad {
304 1.6 riastrad
305 1.6 riastrad atf_tc_set_md_var(tc, "descr",
306 1.6 riastrad "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
307 1.6 riastrad "SIGEV_SIGNAL, using absolute time");
308 1.6 riastrad }
309 1.6 riastrad
310 1.6 riastrad ATF_TC_BODY(timer_create_mono_abs, tc)
311 1.6 riastrad {
312 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, NOEXPIRE, TIMER_ABSTIME);
313 1.3 christos }
314 1.3 christos
315 1.3 christos ATF_TC(timer_create_real_expire);
316 1.3 christos ATF_TC_HEAD(timer_create_real_expire, tc)
317 1.3 christos {
318 1.3 christos
319 1.3 christos atf_tc_set_md_var(tc, "descr",
320 1.3 christos "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
321 1.3 christos "SIGEV_SIGNAL, with expiration");
322 1.3 christos }
323 1.3 christos
324 1.3 christos ATF_TC_BODY(timer_create_real_expire, tc)
325 1.3 christos {
326 1.6 riastrad timer_signal_create(CLOCK_REALTIME, EXPIRE, 0);
327 1.6 riastrad }
328 1.6 riastrad
329 1.6 riastrad ATF_TC(timer_create_real_expire_abs);
330 1.6 riastrad ATF_TC_HEAD(timer_create_real_expire_abs, tc)
331 1.6 riastrad {
332 1.6 riastrad
333 1.6 riastrad atf_tc_set_md_var(tc, "descr",
334 1.6 riastrad "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
335 1.6 riastrad "SIGEV_SIGNAL, with expiration, using absolute time");
336 1.6 riastrad }
337 1.6 riastrad
338 1.6 riastrad ATF_TC_BODY(timer_create_real_expire_abs, tc)
339 1.6 riastrad {
340 1.6 riastrad timer_signal_create(CLOCK_REALTIME, EXPIRE, TIMER_ABSTIME);
341 1.3 christos }
342 1.3 christos
343 1.3 christos ATF_TC(timer_create_mono_expire);
344 1.3 christos ATF_TC_HEAD(timer_create_mono_expire, tc)
345 1.3 christos {
346 1.3 christos
347 1.3 christos atf_tc_set_md_var(tc, "descr",
348 1.3 christos "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
349 1.3 christos "SIGEV_SIGNAL, with expiration");
350 1.3 christos }
351 1.3 christos
352 1.3 christos ATF_TC_BODY(timer_create_mono_expire, tc)
353 1.3 christos {
354 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, EXPIRE, 0);
355 1.6 riastrad }
356 1.6 riastrad
357 1.6 riastrad ATF_TC(timer_create_mono_expire_abs);
358 1.6 riastrad ATF_TC_HEAD(timer_create_mono_expire_abs, tc)
359 1.6 riastrad {
360 1.6 riastrad
361 1.6 riastrad atf_tc_set_md_var(tc, "descr",
362 1.6 riastrad "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
363 1.6 riastrad "SIGEV_SIGNAL, with expiration, using absolute time");
364 1.6 riastrad }
365 1.6 riastrad
366 1.6 riastrad ATF_TC_BODY(timer_create_mono_expire_abs, tc)
367 1.6 riastrad {
368 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, EXPIRE, TIMER_ABSTIME);
369 1.6 riastrad }
370 1.6 riastrad
371 1.6 riastrad ATF_TC(timer_create_real_past);
372 1.6 riastrad ATF_TC_HEAD(timer_create_real_past, tc)
373 1.6 riastrad {
374 1.6 riastrad
375 1.6 riastrad atf_tc_set_md_var(tc, "descr",
376 1.6 riastrad "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
377 1.6 riastrad "SIGEV_SIGNAL, with expiration passed before timer_settime(2)");
378 1.6 riastrad }
379 1.6 riastrad
380 1.6 riastrad ATF_TC_BODY(timer_create_real_past, tc)
381 1.6 riastrad {
382 1.6 riastrad timer_signal_create(CLOCK_REALTIME, PAST, 0);
383 1.6 riastrad }
384 1.6 riastrad
385 1.6 riastrad ATF_TC(timer_create_real_past_abs);
386 1.6 riastrad ATF_TC_HEAD(timer_create_real_past_abs, tc)
387 1.6 riastrad {
388 1.6 riastrad
389 1.6 riastrad atf_tc_set_md_var(tc, "descr",
390 1.6 riastrad "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
391 1.6 riastrad "SIGEV_SIGNAL, with expiration passed before timer_settime(2),"
392 1.6 riastrad " using absolute time");
393 1.6 riastrad }
394 1.6 riastrad
395 1.6 riastrad ATF_TC_BODY(timer_create_real_past_abs, tc)
396 1.6 riastrad {
397 1.6 riastrad timer_signal_create(CLOCK_REALTIME, PAST, TIMER_ABSTIME);
398 1.6 riastrad }
399 1.6 riastrad
400 1.6 riastrad ATF_TC(timer_create_mono_past);
401 1.6 riastrad ATF_TC_HEAD(timer_create_mono_past, tc)
402 1.6 riastrad {
403 1.6 riastrad
404 1.6 riastrad atf_tc_set_md_var(tc, "descr",
405 1.6 riastrad "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
406 1.6 riastrad "SIGEV_SIGNAL, with expiration passed before timer_settime(2)");
407 1.6 riastrad }
408 1.6 riastrad
409 1.6 riastrad ATF_TC_BODY(timer_create_mono_past, tc)
410 1.6 riastrad {
411 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, PAST, 0);
412 1.6 riastrad }
413 1.6 riastrad
414 1.6 riastrad ATF_TC(timer_create_mono_past_abs);
415 1.6 riastrad ATF_TC_HEAD(timer_create_mono_past_abs, tc)
416 1.6 riastrad {
417 1.6 riastrad
418 1.6 riastrad atf_tc_set_md_var(tc, "descr",
419 1.6 riastrad "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
420 1.6 riastrad "SIGEV_SIGNAL, with expiration passed before timer_settime(2),"
421 1.6 riastrad " using absolute time");
422 1.6 riastrad }
423 1.6 riastrad
424 1.6 riastrad ATF_TC_BODY(timer_create_mono_past_abs, tc)
425 1.6 riastrad {
426 1.6 riastrad timer_signal_create(CLOCK_MONOTONIC, PAST, TIMER_ABSTIME);
427 1.6 riastrad }
428 1.6 riastrad
429 1.6 riastrad ATF_TC(timer_invalidtime);
430 1.6 riastrad ATF_TC_HEAD(timer_invalidtime, tc)
431 1.6 riastrad {
432 1.6 riastrad atf_tc_set_md_var(tc, "descr",
433 1.6 riastrad "Verify timer_settime(2) rejects invalid times");
434 1.6 riastrad }
435 1.6 riastrad
436 1.6 riastrad ATF_TC_BODY(timer_invalidtime, tc)
437 1.6 riastrad {
438 1.6 riastrad const struct itimerspec einval_its[] = {
439 1.6 riastrad [0] = { .it_value = { -1, -1 } },
440 1.6 riastrad [1] = { .it_value = { 1, -1 } },
441 1.6 riastrad [2] = { .it_value = { 0, 1000000001 } },
442 1.6 riastrad [3] = { .it_interval = { -1, -1 } },
443 1.6 riastrad [4] = { .it_interval = { 1, -1 } },
444 1.6 riastrad [5] = { .it_interval = { 0, 1000000001 } },
445 1.6 riastrad };
446 1.6 riastrad struct timespec now;
447 1.6 riastrad unsigned i;
448 1.6 riastrad
449 1.6 riastrad RL(clock_gettime(CLOCK_MONOTONIC, &now));
450 1.6 riastrad
451 1.6 riastrad RL(timer_create(CLOCK_MONOTONIC, NULL, &t));
452 1.6 riastrad
453 1.6 riastrad for (i = 0; i < __arraycount(einval_its); i++) {
454 1.6 riastrad struct itimerspec its;
455 1.6 riastrad
456 1.6 riastrad ATF_CHECK_ERRNO(EINVAL,
457 1.6 riastrad timer_settime(t, 0, &einval_its[i], NULL) == -1);
458 1.6 riastrad
459 1.6 riastrad /* Try the same with an absolute time near now. */
460 1.6 riastrad its.it_value = einval_its[i].it_value;
461 1.6 riastrad its.it_value.tv_sec += now.tv_sec + 60;
462 1.6 riastrad ATF_CHECK_ERRNO(EINVAL,
463 1.6 riastrad timer_settime(t, TIMER_ABSTIME, &its, NULL) == -1);
464 1.6 riastrad }
465 1.6 riastrad
466 1.6 riastrad RL(timer_delete(t));
467 1.1 jruoho }
468 1.1 jruoho
469 1.1 jruoho ATF_TP_ADD_TCS(tp)
470 1.1 jruoho {
471 1.1 jruoho
472 1.2 jruoho ATF_TP_ADD_TC(tp, timer_create_err);
473 1.2 jruoho ATF_TP_ADD_TC(tp, timer_create_real);
474 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_real_abs);
475 1.2 jruoho ATF_TP_ADD_TC(tp, timer_create_mono);
476 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_mono_abs);
477 1.3 christos ATF_TP_ADD_TC(tp, timer_create_real_expire);
478 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_real_expire_abs);
479 1.3 christos ATF_TP_ADD_TC(tp, timer_create_mono_expire);
480 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_mono_expire_abs);
481 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_real_past);
482 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_real_past_abs);
483 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_mono_past);
484 1.6 riastrad ATF_TP_ADD_TC(tp, timer_create_mono_past_abs);
485 1.6 riastrad ATF_TP_ADD_TC(tp, timer_invalidtime);
486 1.1 jruoho
487 1.1 jruoho return atf_no_error();
488 1.1 jruoho }
489