xref: /freebsd/tests/sys/kqueue/libkqueue/timer.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
1cb5fe245SEnji Cooper /*
2cb5fe245SEnji Cooper  * Copyright (c) 2009 Mark Heily <mark@heily.com>
3cb5fe245SEnji Cooper  *
4cb5fe245SEnji Cooper  * Permission to use, copy, modify, and distribute this software for any
5cb5fe245SEnji Cooper  * purpose with or without fee is hereby granted, provided that the above
6cb5fe245SEnji Cooper  * copyright notice and this permission notice appear in all copies.
7cb5fe245SEnji Cooper  *
8cb5fe245SEnji Cooper  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9cb5fe245SEnji Cooper  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10cb5fe245SEnji Cooper  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11cb5fe245SEnji Cooper  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12cb5fe245SEnji Cooper  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13cb5fe245SEnji Cooper  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14cb5fe245SEnji Cooper  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15cb5fe245SEnji Cooper  */
16cb5fe245SEnji Cooper 
17cb5fe245SEnji Cooper #include "common.h"
182b34e843SKonstantin Belousov #include <sys/time.h>
19cb5fe245SEnji Cooper 
2095c05062SDavid Bright #define	MILLION 1000000
2195c05062SDavid Bright #define	THOUSAND 1000
2295c05062SDavid Bright #define	SEC_TO_MS(t) ((t) * THOUSAND)	/* Convert seconds to milliseconds. */
2395c05062SDavid Bright #define	SEC_TO_US(t) ((t) * MILLION)	/* Convert seconds to microseconds. */
2495c05062SDavid Bright #define	MS_TO_US(t)  ((t) * THOUSAND)	/* Convert milliseconds to microseconds. */
2595c05062SDavid Bright #define	US_TO_NS(t)  ((t) * THOUSAND)	/* Convert microseconds to nanoseconds. */
2695c05062SDavid Bright 
27cb5fe245SEnji Cooper 
2895c05062SDavid Bright /* Get the current time with microsecond precision. Used for
2995c05062SDavid Bright  * sub-second timing to make some timer tests run faster.
3095c05062SDavid Bright  */
310fbdc372SKyle Evans static uint64_t
now(void)3295c05062SDavid Bright now(void)
3395c05062SDavid Bright {
3495c05062SDavid Bright     struct timeval tv;
3595c05062SDavid Bright 
3695c05062SDavid Bright     gettimeofday(&tv, NULL);
370fbdc372SKyle Evans     /* Promote potentially 32-bit time_t to uint64_t before conversion. */
380fbdc372SKyle Evans     return SEC_TO_US((uint64_t)tv.tv_sec) + tv.tv_usec;
3995c05062SDavid Bright }
4095c05062SDavid Bright 
4195c05062SDavid Bright /* Sleep for a given number of milliseconds. The timeout is assumed to
4295c05062SDavid Bright  * be less than 1 second.
4395c05062SDavid Bright  */
44c9c283bdSAlex Richardson static void
mssleep(int t)4595c05062SDavid Bright mssleep(int t)
4695c05062SDavid Bright {
4795c05062SDavid Bright     struct timespec stime = {
4895c05062SDavid Bright         .tv_sec = 0,
4995c05062SDavid Bright         .tv_nsec = US_TO_NS(MS_TO_US(t)),
5095c05062SDavid Bright     };
5195c05062SDavid Bright 
5295c05062SDavid Bright     nanosleep(&stime, NULL);
5395c05062SDavid Bright }
5495c05062SDavid Bright 
5595c05062SDavid Bright /* Sleep for a given number of microseconds. The timeout is assumed to
5695c05062SDavid Bright  * be less than 1 second.
5795c05062SDavid Bright  */
58c9c283bdSAlex Richardson static void
ussleep(int t)5995c05062SDavid Bright ussleep(int t)
6095c05062SDavid Bright {
6195c05062SDavid Bright     struct timespec stime = {
6295c05062SDavid Bright         .tv_sec = 0,
6395c05062SDavid Bright         .tv_nsec = US_TO_NS(t),
6495c05062SDavid Bright     };
6595c05062SDavid Bright 
6695c05062SDavid Bright     nanosleep(&stime, NULL);
6795c05062SDavid Bright }
6895c05062SDavid Bright 
69c9c283bdSAlex Richardson static void
test_kevent_timer_add(void)70cb5fe245SEnji Cooper test_kevent_timer_add(void)
71cb5fe245SEnji Cooper {
72cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, EV_ADD)";
73cb5fe245SEnji Cooper     struct kevent kev;
74cb5fe245SEnji Cooper 
75cb5fe245SEnji Cooper     test_begin(test_id);
76cb5fe245SEnji Cooper 
77cb5fe245SEnji Cooper     EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
78cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
79cb5fe245SEnji Cooper         err(1, "%s", test_id);
80cb5fe245SEnji Cooper 
81cb5fe245SEnji Cooper     success();
82cb5fe245SEnji Cooper }
83cb5fe245SEnji Cooper 
84c9c283bdSAlex Richardson static void
test_kevent_timer_del(void)85cb5fe245SEnji Cooper test_kevent_timer_del(void)
86cb5fe245SEnji Cooper {
87cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, EV_DELETE)";
88cb5fe245SEnji Cooper     struct kevent kev;
89cb5fe245SEnji Cooper 
90cb5fe245SEnji Cooper     test_begin(test_id);
91cb5fe245SEnji Cooper 
92cb5fe245SEnji Cooper     EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
93cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
94cb5fe245SEnji Cooper         err(1, "%s", test_id);
95cb5fe245SEnji Cooper 
96cb5fe245SEnji Cooper     test_no_kevents();
97cb5fe245SEnji Cooper 
98cb5fe245SEnji Cooper     success();
99cb5fe245SEnji Cooper }
100cb5fe245SEnji Cooper 
101c9c283bdSAlex Richardson static void
test_kevent_timer_get(void)102cb5fe245SEnji Cooper test_kevent_timer_get(void)
103cb5fe245SEnji Cooper {
104cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, wait)";
105cb5fe245SEnji Cooper     struct kevent kev;
106cb5fe245SEnji Cooper 
107cb5fe245SEnji Cooper     test_begin(test_id);
108cb5fe245SEnji Cooper 
109cb5fe245SEnji Cooper     EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
110cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
111cb5fe245SEnji Cooper         err(1, "%s", test_id);
112cb5fe245SEnji Cooper 
113cb5fe245SEnji Cooper     kev.flags |= EV_CLEAR;
114cb5fe245SEnji Cooper     kev.data = 1;
115cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
116cb5fe245SEnji Cooper 
117cb5fe245SEnji Cooper     EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
118cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
119cb5fe245SEnji Cooper         err(1, "%s", test_id);
120cb5fe245SEnji Cooper 
121cb5fe245SEnji Cooper     success();
122cb5fe245SEnji Cooper }
123cb5fe245SEnji Cooper 
124cb5fe245SEnji Cooper static void
test_oneshot(void)125cb5fe245SEnji Cooper test_oneshot(void)
126cb5fe245SEnji Cooper {
127cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, EV_ONESHOT)";
128cb5fe245SEnji Cooper     struct kevent kev;
129cb5fe245SEnji Cooper 
130cb5fe245SEnji Cooper     test_begin(test_id);
131cb5fe245SEnji Cooper 
132cb5fe245SEnji Cooper     test_no_kevents();
133cb5fe245SEnji Cooper 
134cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500,NULL);
135cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
136cb5fe245SEnji Cooper         err(1, "%s", test_id);
137cb5fe245SEnji Cooper 
138cb5fe245SEnji Cooper     /* Retrieve the event */
139cb5fe245SEnji Cooper     kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT;
140cb5fe245SEnji Cooper     kev.data = 1;
141cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
142cb5fe245SEnji Cooper 
143cb5fe245SEnji Cooper     /* Check if the event occurs again */
144cb5fe245SEnji Cooper     sleep(3);
145cb5fe245SEnji Cooper     test_no_kevents();
146cb5fe245SEnji Cooper 
147cb5fe245SEnji Cooper 
148cb5fe245SEnji Cooper     success();
149cb5fe245SEnji Cooper }
150cb5fe245SEnji Cooper 
151cb5fe245SEnji Cooper static void
test_periodic(void)152cb5fe245SEnji Cooper test_periodic(void)
153cb5fe245SEnji Cooper {
154cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, periodic)";
155cb5fe245SEnji Cooper     struct kevent kev;
156cb5fe245SEnji Cooper 
157cb5fe245SEnji Cooper     test_begin(test_id);
158cb5fe245SEnji Cooper 
159cb5fe245SEnji Cooper     test_no_kevents();
160cb5fe245SEnji Cooper 
161cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000,NULL);
162cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
163cb5fe245SEnji Cooper         err(1, "%s", test_id);
164cb5fe245SEnji Cooper 
165cb5fe245SEnji Cooper     /* Retrieve the event */
166cb5fe245SEnji Cooper     kev.flags = EV_ADD | EV_CLEAR;
167cb5fe245SEnji Cooper     kev.data = 1;
168cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
169cb5fe245SEnji Cooper 
170cb5fe245SEnji Cooper     /* Check if the event occurs again */
171cb5fe245SEnji Cooper     sleep(1);
172cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
173cb5fe245SEnji Cooper 
174cb5fe245SEnji Cooper     /* Delete the event */
175cb5fe245SEnji Cooper     kev.flags = EV_DELETE;
176cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
177cb5fe245SEnji Cooper         err(1, "%s", test_id);
178cb5fe245SEnji Cooper 
179cb5fe245SEnji Cooper     success();
180cb5fe245SEnji Cooper }
181cb5fe245SEnji Cooper 
182cb5fe245SEnji Cooper static void
test_periodic_modify(void)183*d6d4f9b4SMark Johnston test_periodic_modify(void)
184*d6d4f9b4SMark Johnston {
185*d6d4f9b4SMark Johnston     const char *test_id = "kevent(EVFILT_TIMER, periodic_modify)";
186*d6d4f9b4SMark Johnston     struct kevent kev;
187*d6d4f9b4SMark Johnston 
188*d6d4f9b4SMark Johnston     test_begin(test_id);
189*d6d4f9b4SMark Johnston 
190*d6d4f9b4SMark Johnston     test_no_kevents();
191*d6d4f9b4SMark Johnston 
192*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
193*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
194*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
195*d6d4f9b4SMark Johnston 
196*d6d4f9b4SMark Johnston     /* Retrieve the event */
197*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR;
198*d6d4f9b4SMark Johnston     kev.data = 1;
199*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
200*d6d4f9b4SMark Johnston 
201*d6d4f9b4SMark Johnston     /* Check if the event occurs again */
202*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 500, NULL);
203*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
204*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
205*d6d4f9b4SMark Johnston 
206*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR;
207*d6d4f9b4SMark Johnston     sleep(1);
208*d6d4f9b4SMark Johnston     kev.data = 2;	/* Should have fired twice */
209*d6d4f9b4SMark Johnston 
210*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
211*d6d4f9b4SMark Johnston 
212*d6d4f9b4SMark Johnston     /* Delete the event */
213*d6d4f9b4SMark Johnston     kev.flags = EV_DELETE;
214*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
215*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
216*d6d4f9b4SMark Johnston 
217*d6d4f9b4SMark Johnston     success();
218*d6d4f9b4SMark Johnston }
219*d6d4f9b4SMark Johnston 
220*d6d4f9b4SMark Johnston #if WITH_NATIVE_KQUEUE_BUGS
221*d6d4f9b4SMark Johnston static void
test_periodic_to_oneshot(void)222*d6d4f9b4SMark Johnston test_periodic_to_oneshot(void)
223*d6d4f9b4SMark Johnston {
224*d6d4f9b4SMark Johnston     const char *test_id = "kevent(EVFILT_TIMER, period_to_oneshot)";
225*d6d4f9b4SMark Johnston     struct kevent kev;
226*d6d4f9b4SMark Johnston 
227*d6d4f9b4SMark Johnston     test_begin(test_id);
228*d6d4f9b4SMark Johnston 
229*d6d4f9b4SMark Johnston     test_no_kevents();
230*d6d4f9b4SMark Johnston 
231*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000, NULL);
232*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
233*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
234*d6d4f9b4SMark Johnston 
235*d6d4f9b4SMark Johnston     /* Retrieve the event */
236*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR;
237*d6d4f9b4SMark Johnston     kev.data = 1;
238*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
239*d6d4f9b4SMark Johnston 
240*d6d4f9b4SMark Johnston     /* Check if the event occurs again */
241*d6d4f9b4SMark Johnston     sleep(1);
242*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
243*d6d4f9b4SMark Johnston 
244*d6d4f9b4SMark Johnston     /* Switch to oneshot */
245*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500, NULL);
246*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
247*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
248*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT;
249*d6d4f9b4SMark Johnston 
250*d6d4f9b4SMark Johnston     sleep(1);
251*d6d4f9b4SMark Johnston     kev.data = 1;	/* Should have fired once */
252*d6d4f9b4SMark Johnston 
253*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
254*d6d4f9b4SMark Johnston 
255*d6d4f9b4SMark Johnston     success();
256*d6d4f9b4SMark Johnston }
257*d6d4f9b4SMark Johnston #endif
258*d6d4f9b4SMark Johnston 
259*d6d4f9b4SMark Johnston static void
test_disable_and_enable(void)260*d6d4f9b4SMark Johnston test_disable_and_enable(void)
261cb5fe245SEnji Cooper {
262cb5fe245SEnji Cooper     const char *test_id = "kevent(EVFILT_TIMER, EV_DISABLE and EV_ENABLE)";
263cb5fe245SEnji Cooper     struct kevent kev;
264cb5fe245SEnji Cooper 
265cb5fe245SEnji Cooper     test_begin(test_id);
266cb5fe245SEnji Cooper 
267cb5fe245SEnji Cooper     test_no_kevents();
268cb5fe245SEnji Cooper 
269cb5fe245SEnji Cooper     /* Add the watch and immediately disable it */
270cb5fe245SEnji Cooper     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 2000,NULL);
271cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
272cb5fe245SEnji Cooper         err(1, "%s", test_id);
273cb5fe245SEnji Cooper     kev.flags = EV_DISABLE;
274cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
275cb5fe245SEnji Cooper         err(1, "%s", test_id);
276cb5fe245SEnji Cooper     test_no_kevents();
277cb5fe245SEnji Cooper 
278cb5fe245SEnji Cooper     /* Re-enable and check again */
279cb5fe245SEnji Cooper     kev.flags = EV_ENABLE;
280cb5fe245SEnji Cooper     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
281cb5fe245SEnji Cooper         err(1, "%s", test_id);
282cb5fe245SEnji Cooper 
283cb5fe245SEnji Cooper     kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT;
284cb5fe245SEnji Cooper     kev.data = 1;
285cb5fe245SEnji Cooper     kevent_cmp(&kev, kevent_get(kqfd));
286cb5fe245SEnji Cooper 
287cb5fe245SEnji Cooper     success();
288cb5fe245SEnji Cooper }
289cb5fe245SEnji Cooper 
2902b34e843SKonstantin Belousov static void
test_abstime(void)2912b34e843SKonstantin Belousov test_abstime(void)
2922b34e843SKonstantin Belousov {
2932b34e843SKonstantin Belousov     const char *test_id = "kevent(EVFILT_TIMER, EV_ONESHOT, NOTE_ABSTIME)";
2942b34e843SKonstantin Belousov     struct kevent kev;
2950fbdc372SKyle Evans     uint64_t end, start, stop;
296c17dd0e8SKyle Evans     const int timeout_sec = 3;
2972b34e843SKonstantin Belousov 
2982b34e843SKonstantin Belousov     test_begin(test_id);
2992b34e843SKonstantin Belousov 
3002b34e843SKonstantin Belousov     test_no_kevents();
3012b34e843SKonstantin Belousov 
302c17dd0e8SKyle Evans     start = now();
303c17dd0e8SKyle Evans     end = start + SEC_TO_US(timeout_sec);
3042b34e843SKonstantin Belousov     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
305c17dd0e8SKyle Evans       NOTE_ABSTIME | NOTE_USECONDS, end, NULL);
3062b34e843SKonstantin Belousov     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
3072b34e843SKonstantin Belousov         err(1, "%s", test_id);
3082b34e843SKonstantin Belousov 
3092b34e843SKonstantin Belousov     /* Retrieve the event */
3102b34e843SKonstantin Belousov     kev.flags = EV_ADD | EV_ONESHOT;
3112b34e843SKonstantin Belousov     kev.data = 1;
3122b34e843SKonstantin Belousov     kev.fflags = 0;
3132b34e843SKonstantin Belousov     kevent_cmp(&kev, kevent_get(kqfd));
3142b34e843SKonstantin Belousov 
315c17dd0e8SKyle Evans     stop = now();
316c17dd0e8SKyle Evans     if (stop < end)
317c17dd0e8SKyle Evans         err(1, "too early %jd %jd", (intmax_t)stop, (intmax_t)end);
3182b34e843SKonstantin Belousov     /* Check if the event occurs again */
3192b34e843SKonstantin Belousov     sleep(3);
3202b34e843SKonstantin Belousov     test_no_kevents();
3212b34e843SKonstantin Belousov 
3222b34e843SKonstantin Belousov     success();
3232b34e843SKonstantin Belousov }
3242b34e843SKonstantin Belousov 
32595c05062SDavid Bright static void
test_abstime_epoch(void)3262f4dbe27SKyle Evans test_abstime_epoch(void)
3272f4dbe27SKyle Evans {
3282f4dbe27SKyle Evans     const char *test_id = "kevent(EVFILT_TIMER (EPOCH), NOTE_ABSTIME)";
3292f4dbe27SKyle Evans     struct kevent kev;
3302f4dbe27SKyle Evans 
3312f4dbe27SKyle Evans     test_begin(test_id);
3322f4dbe27SKyle Evans 
3332f4dbe27SKyle Evans     test_no_kevents();
3342f4dbe27SKyle Evans 
3352f4dbe27SKyle Evans     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, NOTE_ABSTIME, 0,
3362f4dbe27SKyle Evans         NULL);
3372f4dbe27SKyle Evans     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
3382f4dbe27SKyle Evans         err(1, "%s", test_id);
3392f4dbe27SKyle Evans 
3402f4dbe27SKyle Evans     /* Retrieve the event */
3412f4dbe27SKyle Evans     kev.flags = EV_ADD;
3422f4dbe27SKyle Evans     kev.data = 1;
3432f4dbe27SKyle Evans     kev.fflags = 0;
3442f4dbe27SKyle Evans     kevent_cmp(&kev, kevent_get(kqfd));
3452f4dbe27SKyle Evans 
3462f4dbe27SKyle Evans     /* Delete the event */
3472f4dbe27SKyle Evans     kev.flags = EV_DELETE;
3482f4dbe27SKyle Evans     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
3492f4dbe27SKyle Evans         err(1, "%s", test_id);
3502f4dbe27SKyle Evans 
3512f4dbe27SKyle Evans     success();
3522f4dbe27SKyle Evans }
3532f4dbe27SKyle Evans 
3542f4dbe27SKyle Evans static void
test_abstime_preboot(void)3559c999a25SKyle Evans test_abstime_preboot(void)
3569c999a25SKyle Evans {
3579c999a25SKyle Evans     const char *test_id = "kevent(EVFILT_TIMER (PREBOOT), EV_ONESHOT, NOTE_ABSTIME)";
3589c999a25SKyle Evans     struct kevent kev;
3599c999a25SKyle Evans     struct timespec btp;
3609c999a25SKyle Evans     uint64_t end, start, stop;
3619c999a25SKyle Evans 
3629c999a25SKyle Evans     test_begin(test_id);
3639c999a25SKyle Evans 
3649c999a25SKyle Evans     test_no_kevents();
3659c999a25SKyle Evans 
3669c999a25SKyle Evans     /*
3679c999a25SKyle Evans      * We'll expire it at just before system boot (roughly) with the hope that
3689c999a25SKyle Evans      * we'll get an ~immediate expiration, just as we do for any value specified
3699c999a25SKyle Evans      * between system boot and now.
3709c999a25SKyle Evans      */
3719c999a25SKyle Evans     start = now();
3729c999a25SKyle Evans     if (clock_gettime(CLOCK_BOOTTIME, &btp) != 0)
3739c999a25SKyle Evans       err(1, "%s", test_id);
3749c999a25SKyle Evans 
3759c999a25SKyle Evans     end = start - SEC_TO_US(btp.tv_sec + 1);
3769c999a25SKyle Evans     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
3779c999a25SKyle Evans       NOTE_ABSTIME | NOTE_USECONDS, end, NULL);
3789c999a25SKyle Evans     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
3799c999a25SKyle Evans         err(1, "%s", test_id);
3809c999a25SKyle Evans 
3819c999a25SKyle Evans     /* Retrieve the event */
3829c999a25SKyle Evans     kev.flags = EV_ADD | EV_ONESHOT;
3839c999a25SKyle Evans     kev.data = 1;
3849c999a25SKyle Evans     kev.fflags = 0;
3859c999a25SKyle Evans     kevent_cmp(&kev, kevent_get(kqfd));
3869c999a25SKyle Evans 
3879c999a25SKyle Evans     stop = now();
3889c999a25SKyle Evans     if (stop < end)
3899c999a25SKyle Evans         err(1, "too early %jd %jd", (intmax_t)stop, (intmax_t)end);
3909c999a25SKyle Evans     /* Check if the event occurs again */
3919c999a25SKyle Evans     sleep(3);
3929c999a25SKyle Evans     test_no_kevents();
3939c999a25SKyle Evans 
3949c999a25SKyle Evans     success();
3959c999a25SKyle Evans }
3969c999a25SKyle Evans 
3979c999a25SKyle Evans static void
test_abstime_postboot(void)3989c999a25SKyle Evans test_abstime_postboot(void)
3999c999a25SKyle Evans {
4009c999a25SKyle Evans     const char *test_id = "kevent(EVFILT_TIMER (POSTBOOT), EV_ONESHOT, NOTE_ABSTIME)";
4019c999a25SKyle Evans     struct kevent kev;
4029c999a25SKyle Evans     uint64_t end, start, stop;
4039c999a25SKyle Evans     const int timeout_sec = 1;
4049c999a25SKyle Evans 
4059c999a25SKyle Evans     test_begin(test_id);
4069c999a25SKyle Evans 
4079c999a25SKyle Evans     test_no_kevents();
4089c999a25SKyle Evans 
4099c999a25SKyle Evans     /*
4109c999a25SKyle Evans      * Set a timer for 1 second ago, it should fire immediately rather than
4119c999a25SKyle Evans      * being rejected.
4129c999a25SKyle Evans      */
4139c999a25SKyle Evans     start = now();
4149c999a25SKyle Evans     end = start - SEC_TO_US(timeout_sec);
4159c999a25SKyle Evans     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
4169c999a25SKyle Evans       NOTE_ABSTIME | NOTE_USECONDS, end, NULL);
4179c999a25SKyle Evans     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
4189c999a25SKyle Evans         err(1, "%s", test_id);
4199c999a25SKyle Evans 
4209c999a25SKyle Evans     /* Retrieve the event */
4219c999a25SKyle Evans     kev.flags = EV_ADD | EV_ONESHOT;
4229c999a25SKyle Evans     kev.data = 1;
4239c999a25SKyle Evans     kev.fflags = 0;
4249c999a25SKyle Evans     kevent_cmp(&kev, kevent_get(kqfd));
4259c999a25SKyle Evans 
4269c999a25SKyle Evans     stop = now();
4279c999a25SKyle Evans     if (stop < end)
4289c999a25SKyle Evans         err(1, "too early %jd %jd", (intmax_t)stop, (intmax_t)end);
4299c999a25SKyle Evans     /* Check if the event occurs again */
4309c999a25SKyle Evans     sleep(3);
4319c999a25SKyle Evans     test_no_kevents();
4329c999a25SKyle Evans 
4339c999a25SKyle Evans     success();
4349c999a25SKyle Evans }
4359c999a25SKyle Evans 
4369c999a25SKyle Evans static void
test_update(void)43795c05062SDavid Bright test_update(void)
43895c05062SDavid Bright {
43995c05062SDavid Bright     const char *test_id = "kevent(EVFILT_TIMER (UPDATE), EV_ADD | EV_ONESHOT)";
44095c05062SDavid Bright     struct kevent kev;
44195c05062SDavid Bright     long elapsed;
4420fbdc372SKyle Evans     uint64_t start;
44395c05062SDavid Bright 
44495c05062SDavid Bright     test_begin(test_id);
44595c05062SDavid Bright 
44695c05062SDavid Bright     test_no_kevents();
44795c05062SDavid Bright 
44895c05062SDavid Bright     /* First set the timer to 1 second */
44995c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
45095c05062SDavid Bright         NOTE_USECONDS, SEC_TO_US(1), (void *)1);
45195c05062SDavid Bright     start = now();
45295c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
45395c05062SDavid Bright         err(1, "%s", test_id);
45495c05062SDavid Bright 
45595c05062SDavid Bright     /* Now reduce the timer to 1 ms */
45695c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
45795c05062SDavid Bright         NOTE_USECONDS, MS_TO_US(1), (void *)2);
45895c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
45995c05062SDavid Bright         err(1, "%s", test_id);
46095c05062SDavid Bright 
46195c05062SDavid Bright     /* Wait for the event */
46295c05062SDavid Bright     kev.flags |= EV_CLEAR;
46395c05062SDavid Bright     kev.fflags &= ~NOTE_USECONDS;
46495c05062SDavid Bright     kev.data = 1;
46595c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
46695c05062SDavid Bright     elapsed = now() - start;
46795c05062SDavid Bright 
46895c05062SDavid Bright     /* Check that the timer expired after at least 1 ms, but less than
46995c05062SDavid Bright      * 1 second. This check is to make sure that the original 1 second
47095c05062SDavid Bright      * timeout was not used.
47195c05062SDavid Bright      */
47295c05062SDavid Bright     printf("timer expired after %ld us\n", elapsed);
47395c05062SDavid Bright     if (elapsed < MS_TO_US(1))
47495c05062SDavid Bright         errx(1, "early timer expiration: %ld us", elapsed);
47595c05062SDavid Bright     if (elapsed > SEC_TO_US(1))
47695c05062SDavid Bright         errx(1, "late timer expiration: %ld us", elapsed);
47795c05062SDavid Bright 
47895c05062SDavid Bright     success();
47995c05062SDavid Bright }
48095c05062SDavid Bright 
48195c05062SDavid Bright static void
test_update_equal(void)48295c05062SDavid Bright test_update_equal(void)
48395c05062SDavid Bright {
48495c05062SDavid Bright     const char *test_id = "kevent(EVFILT_TIMER (UPDATE=), EV_ADD | EV_ONESHOT)";
48595c05062SDavid Bright     struct kevent kev;
48695c05062SDavid Bright     long elapsed;
4870fbdc372SKyle Evans     uint64_t start;
48895c05062SDavid Bright 
48995c05062SDavid Bright     test_begin(test_id);
49095c05062SDavid Bright 
49195c05062SDavid Bright     test_no_kevents();
49295c05062SDavid Bright 
49395c05062SDavid Bright     /* First set the timer to 1 ms */
49495c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
49595c05062SDavid Bright         NOTE_USECONDS, MS_TO_US(1), NULL);
49695c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
49795c05062SDavid Bright         err(1, "%s", test_id);
49895c05062SDavid Bright 
49995c05062SDavid Bright     /* Sleep for a significant fraction of the timeout. */
50095c05062SDavid Bright     ussleep(600);
50195c05062SDavid Bright 
50295c05062SDavid Bright     /* Now re-add the timer with the same parameters */
50395c05062SDavid Bright     start = now();
50495c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
50595c05062SDavid Bright         err(1, "%s", test_id);
50695c05062SDavid Bright 
50795c05062SDavid Bright     /* Wait for the event */
50895c05062SDavid Bright     kev.flags |= EV_CLEAR;
50995c05062SDavid Bright     kev.fflags &= ~NOTE_USECONDS;
51095c05062SDavid Bright     kev.data = 1;
51195c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
51295c05062SDavid Bright     elapsed = now() - start;
51395c05062SDavid Bright 
51495c05062SDavid Bright     /* Check that the timer expired after at least 1 ms. This check is
51595c05062SDavid Bright      * to make sure that the timer re-started and that the event is
51695c05062SDavid Bright      * not from the original add of the timer.
51795c05062SDavid Bright      */
51895c05062SDavid Bright     printf("timer expired after %ld us\n", elapsed);
51995c05062SDavid Bright     if (elapsed < MS_TO_US(1))
52095c05062SDavid Bright         errx(1, "early timer expiration: %ld us", elapsed);
52195c05062SDavid Bright 
52295c05062SDavid Bright     success();
52395c05062SDavid Bright }
52495c05062SDavid Bright 
52595c05062SDavid Bright static void
test_update_expired(void)52695c05062SDavid Bright test_update_expired(void)
52795c05062SDavid Bright {
52895c05062SDavid Bright     const char *test_id = "kevent(EVFILT_TIMER (UPDATE EXP), EV_ADD | EV_ONESHOT)";
52995c05062SDavid Bright     struct kevent kev;
53095c05062SDavid Bright     long elapsed;
5310fbdc372SKyle Evans     uint64_t start;
53295c05062SDavid Bright 
53395c05062SDavid Bright     test_begin(test_id);
53495c05062SDavid Bright 
53595c05062SDavid Bright     test_no_kevents();
53695c05062SDavid Bright 
53795c05062SDavid Bright     /* Set the timer to 1ms */
53895c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
53995c05062SDavid Bright         NOTE_USECONDS, MS_TO_US(1), NULL);
54095c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
54195c05062SDavid Bright         err(1, "%s", test_id);
54295c05062SDavid Bright 
54395c05062SDavid Bright     /* Wait for 2 ms to give the timer plenty of time to expire. */
54495c05062SDavid Bright     mssleep(2);
54595c05062SDavid Bright 
54695c05062SDavid Bright     /* Now re-add the timer */
54795c05062SDavid Bright     start = now();
54895c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
54995c05062SDavid Bright         err(1, "%s", test_id);
55095c05062SDavid Bright 
55195c05062SDavid Bright     /* Wait for the event */
55295c05062SDavid Bright     kev.flags |= EV_CLEAR;
55395c05062SDavid Bright     kev.fflags &= ~NOTE_USECONDS;
55495c05062SDavid Bright     kev.data = 1;
55595c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
55695c05062SDavid Bright     elapsed = now() - start;
55795c05062SDavid Bright 
55895c05062SDavid Bright     /* Check that the timer expired after at least 1 ms.  This check
55995c05062SDavid Bright      * is to make sure that the timer re-started and that the event is
56095c05062SDavid Bright      * not from the original add (and expiration) of the timer.
56195c05062SDavid Bright      */
56295c05062SDavid Bright     printf("timer expired after %ld us\n", elapsed);
56395c05062SDavid Bright     if (elapsed < MS_TO_US(1))
56495c05062SDavid Bright         errx(1, "early timer expiration: %ld us", elapsed);
56595c05062SDavid Bright 
56695c05062SDavid Bright     /* Make sure the re-added timer does not fire. In other words,
56795c05062SDavid Bright      * test that the event received above was the only event from the
56895c05062SDavid Bright      * add and re-add of the timer.
56995c05062SDavid Bright      */
57095c05062SDavid Bright     mssleep(2);
57195c05062SDavid Bright     test_no_kevents();
57295c05062SDavid Bright 
57395c05062SDavid Bright     success();
57495c05062SDavid Bright }
57595c05062SDavid Bright 
57695c05062SDavid Bright static void
test_update_periodic(void)57795c05062SDavid Bright test_update_periodic(void)
57895c05062SDavid Bright {
57995c05062SDavid Bright     const char *test_id = "kevent(EVFILT_TIMER (UPDATE), periodic)";
58095c05062SDavid Bright     struct kevent kev;
58195c05062SDavid Bright     long elapsed;
5820fbdc372SKyle Evans     uint64_t start, stop;
58395c05062SDavid Bright 
58495c05062SDavid Bright     test_begin(test_id);
58595c05062SDavid Bright 
58695c05062SDavid Bright     test_no_kevents();
58795c05062SDavid Bright 
58895c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, SEC_TO_MS(1), NULL);
58995c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
59095c05062SDavid Bright         err(1, "%s", test_id);
59195c05062SDavid Bright 
59295c05062SDavid Bright     /* Retrieve the event */
59395c05062SDavid Bright     kev.flags = EV_ADD | EV_CLEAR;
59495c05062SDavid Bright     kev.data = 1;
59595c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
59695c05062SDavid Bright 
59795c05062SDavid Bright     /* Check if the event occurs again */
59895c05062SDavid Bright     sleep(1);
59995c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
60095c05062SDavid Bright 
60195c05062SDavid Bright     /* Re-add with new timeout. */
60295c05062SDavid Bright     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, SEC_TO_MS(2), NULL);
60395c05062SDavid Bright     start = now();
60495c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
60595c05062SDavid Bright         err(1, "%s", test_id);
60695c05062SDavid Bright 
60795c05062SDavid Bright     /* Retrieve the event */
60895c05062SDavid Bright     kev.flags = EV_ADD | EV_CLEAR;
60995c05062SDavid Bright     kev.data = 1;
61095c05062SDavid Bright     kevent_cmp(&kev, kevent_get(kqfd));
61195c05062SDavid Bright 
61295c05062SDavid Bright     stop = now();
61395c05062SDavid Bright     elapsed = stop - start;
61495c05062SDavid Bright 
61595c05062SDavid Bright     /* Check that the timer expired after at least 2 ms.
61695c05062SDavid Bright      */
61795c05062SDavid Bright     printf("timer expired after %ld us\n", elapsed);
61895c05062SDavid Bright     if (elapsed < MS_TO_US(2))
61995c05062SDavid Bright         errx(1, "early timer expiration: %ld us", elapsed);
62095c05062SDavid Bright 
62195c05062SDavid Bright     /* Delete the event */
62295c05062SDavid Bright     kev.flags = EV_DELETE;
62395c05062SDavid Bright     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
62495c05062SDavid Bright         err(1, "%s", test_id);
62595c05062SDavid Bright 
62695c05062SDavid Bright     success();
62795c05062SDavid Bright }
62895c05062SDavid Bright 
62995c05062SDavid Bright static void
test_update_timing(void)63095c05062SDavid Bright test_update_timing(void)
63195c05062SDavid Bright {
63295c05062SDavid Bright #define	MIN_SLEEP 500
63395c05062SDavid Bright #define	MAX_SLEEP 1500
63495c05062SDavid Bright     const char *test_id = "kevent(EVFILT_TIMER (UPDATE TIMING), EV_ADD | EV_ONESHOT)";
63595c05062SDavid Bright     struct kevent kev;
63695c05062SDavid Bright     int iteration;
63795c05062SDavid Bright     int sleeptime;
63895c05062SDavid Bright     long elapsed;
6390fbdc372SKyle Evans     uint64_t start, stop;
64095c05062SDavid Bright 
64195c05062SDavid Bright     test_begin(test_id);
64295c05062SDavid Bright 
64395c05062SDavid Bright     test_no_kevents();
64495c05062SDavid Bright 
64595c05062SDavid Bright     /* Re-try the update tests with a variety of delays between the
64695c05062SDavid Bright      * original timer activation and the update of the timer. The goal
64795c05062SDavid Bright      * is to show that in all cases the only timer event that is
64895c05062SDavid Bright      * received is from the update and not the original timer add.
64995c05062SDavid Bright      */
65095c05062SDavid Bright     for (sleeptime = MIN_SLEEP, iteration = 1;
65195c05062SDavid Bright          sleeptime < MAX_SLEEP;
65295c05062SDavid Bright          ++sleeptime, ++iteration) {
65395c05062SDavid Bright 
65495c05062SDavid Bright         /* First set the timer to 1 ms */
65595c05062SDavid Bright         EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
65695c05062SDavid Bright             NOTE_USECONDS, MS_TO_US(1), NULL);
65795c05062SDavid Bright         if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
65895c05062SDavid Bright             err(1, "%s", test_id);
65995c05062SDavid Bright 
66095c05062SDavid Bright         /* Delay; the delay ranges from less than to greater than the
66195c05062SDavid Bright          * timer period.
66295c05062SDavid Bright          */
66395c05062SDavid Bright         ussleep(sleeptime);
66495c05062SDavid Bright 
66595c05062SDavid Bright         /* Now re-add the timer with the same parameters */
66695c05062SDavid Bright         start = now();
66795c05062SDavid Bright         if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
66895c05062SDavid Bright             err(1, "%s", test_id);
66995c05062SDavid Bright 
67095c05062SDavid Bright         /* Wait for the event */
67195c05062SDavid Bright         kev.flags |= EV_CLEAR;
67295c05062SDavid Bright         kev.fflags &= ~NOTE_USECONDS;
67395c05062SDavid Bright         kev.data = 1;
67495c05062SDavid Bright         kevent_cmp(&kev, kevent_get(kqfd));
67595c05062SDavid Bright         stop = now();
67695c05062SDavid Bright         elapsed = stop - start;
67795c05062SDavid Bright 
67895c05062SDavid Bright         /* Check that the timer expired after at least 1 ms. This
67995c05062SDavid Bright          * check is to make sure that the timer re-started and that
68095c05062SDavid Bright          * the event is not from the original add of the timer.
68195c05062SDavid Bright          */
68295c05062SDavid Bright         if (elapsed < MS_TO_US(1))
68395c05062SDavid Bright             errx(1, "early timer expiration: %ld us", elapsed);
68495c05062SDavid Bright 
68595c05062SDavid Bright         /* Make sure the re-added timer does not fire. In other words,
68695c05062SDavid Bright          * test that the event received above was the only event from
68795c05062SDavid Bright          * the add and re-add of the timer.
68895c05062SDavid Bright          */
68995c05062SDavid Bright         mssleep(2);
69095c05062SDavid Bright         test_no_kevents_quietly();
69195c05062SDavid Bright     }
69295c05062SDavid Bright 
69395c05062SDavid Bright     success();
69495c05062SDavid Bright }
69595c05062SDavid Bright 
696*d6d4f9b4SMark Johnston static void
test_dispatch(void)697*d6d4f9b4SMark Johnston test_dispatch(void)
698*d6d4f9b4SMark Johnston {
699*d6d4f9b4SMark Johnston     const char *test_id = "kevent(EVFILT_TIMER, EV_ADD | EV_DISPATCH)";
700*d6d4f9b4SMark Johnston     struct kevent kev;
701*d6d4f9b4SMark Johnston 
702*d6d4f9b4SMark Johnston     test_no_kevents();
703*d6d4f9b4SMark Johnston 
704*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_DISPATCH, 0, 200, NULL);
705*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
706*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
707*d6d4f9b4SMark Johnston 
708*d6d4f9b4SMark Johnston     /* Get one event */
709*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH;
710*d6d4f9b4SMark Johnston     kev.data = 1;
711*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
712*d6d4f9b4SMark Johnston 
713*d6d4f9b4SMark Johnston     /* Confirm that the knote is disabled due to EV_DISPATCH */
714*d6d4f9b4SMark Johnston     usleep(500000);
715*d6d4f9b4SMark Johnston     test_no_kevents();
716*d6d4f9b4SMark Johnston 
717*d6d4f9b4SMark Johnston     /* Enable the knote and make sure no events are pending */
718*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_DISPATCH, 0, 200, NULL);
719*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
720*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
721*d6d4f9b4SMark Johnston     test_no_kevents();
722*d6d4f9b4SMark Johnston 
723*d6d4f9b4SMark Johnston     /* Get the next event */
724*d6d4f9b4SMark Johnston     usleep(1100000); /* 1100 ms */
725*d6d4f9b4SMark Johnston     kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH;
726*d6d4f9b4SMark Johnston     kev.data = 5;
727*d6d4f9b4SMark Johnston     kevent_cmp(&kev, kevent_get(kqfd));
728*d6d4f9b4SMark Johnston 
729*d6d4f9b4SMark Johnston     /* Remove the knote and ensure the event no longer fires */
730*d6d4f9b4SMark Johnston     EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
731*d6d4f9b4SMark Johnston     if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
732*d6d4f9b4SMark Johnston         err(1, "%s", test_id);
733*d6d4f9b4SMark Johnston     usleep(500000); /* 500ms */
734*d6d4f9b4SMark Johnston     test_no_kevents();
735*d6d4f9b4SMark Johnston 
736*d6d4f9b4SMark Johnston     success();
737*d6d4f9b4SMark Johnston }
738*d6d4f9b4SMark Johnston 
739cb5fe245SEnji Cooper void
test_evfilt_timer(void)740c9c283bdSAlex Richardson test_evfilt_timer(void)
741cb5fe245SEnji Cooper {
742cb5fe245SEnji Cooper     kqfd = kqueue();
743cb5fe245SEnji Cooper     test_kevent_timer_add();
744cb5fe245SEnji Cooper     test_kevent_timer_del();
745cb5fe245SEnji Cooper     test_kevent_timer_get();
746cb5fe245SEnji Cooper     test_oneshot();
747cb5fe245SEnji Cooper     test_periodic();
748*d6d4f9b4SMark Johnston     test_periodic_modify();
749*d6d4f9b4SMark Johnston #if WITH_NATIVE_KQUEUE_BUGS
750*d6d4f9b4SMark Johnston     test_periodic_to_oneshot();
751*d6d4f9b4SMark Johnston #endif
7522b34e843SKonstantin Belousov     test_abstime();
7532f4dbe27SKyle Evans     test_abstime_epoch();
7549c999a25SKyle Evans     test_abstime_preboot();
7559c999a25SKyle Evans     test_abstime_postboot();
75695c05062SDavid Bright     test_update();
75795c05062SDavid Bright     test_update_equal();
75895c05062SDavid Bright     test_update_expired();
75995c05062SDavid Bright     test_update_timing();
76095c05062SDavid Bright     test_update_periodic();
761*d6d4f9b4SMark Johnston     test_disable_and_enable();
762*d6d4f9b4SMark Johnston     test_dispatch();
763cb5fe245SEnji Cooper     close(kqfd);
764cb5fe245SEnji Cooper }
765