]>
git.saurik.com Git - apple/xnu.git/blob - tools/tests/kqueue_tests/kqueue_timer_tests.c
9 int kq
, passed
, failed
;
12 * Wait for given kevent, which should return in 'expected' usecs.
15 do_simple_kevent(struct kevent64_s
*kev
, uint64_t expected
)
18 uint64_t elapsed_usecs
, delta_usecs
;
19 struct timespec timeout
;
20 struct timeval before
, after
;
22 /* time out after 1 sec extra delay */
23 timeout
.tv_sec
= (expected
/ (1000 * 1000)) + 1;
24 timeout
.tv_nsec
= (expected
% (1000 * 1000)) * 1000;
26 /* measure time for the kevent */
27 gettimeofday(&before
, NULL
);
28 ret
= kevent64(kq
, kev
, 1, kev
, 1, 0, &timeout
);
29 gettimeofday(&after
, NULL
);
31 if (ret
< 1 || (kev
->flags
& EV_ERROR
)) {
32 printf("\tfailure: kevent returned %d, error %d\n", ret
,
33 (ret
== -1 ? errno
: (int) kev
->data
));
38 elapsed_usecs
= (after
.tv_sec
- before
.tv_sec
) * (1000 * 1000) +
39 (after
.tv_usec
- before
.tv_usec
);
40 delta_usecs
= abs(elapsed_usecs
- (expected
));
42 /* failure if we're 30% off, or 50 mics late */
43 if (delta_usecs
> (30 * expected
/ 100.0) && delta_usecs
> 50) {
44 printf("\tfailure: expected %lld usec, measured %lld usec.\n",
45 expected
, elapsed_usecs
);
48 printf("\tsuccess.\n");
54 test_absolute_kevent(int time
, int scale
)
57 struct kevent64_s kev
;
58 uint64_t nowus
, expected
, deadline
;
62 gettimeofday(&tv
, NULL
);
63 nowus
= tv
.tv_sec
* (1000 * 1000LL) + tv
.tv_usec
;
67 printf("Testing %d sec absolute timer...\n", time
);
68 timescale
= 1000 * 1000;
71 printf("Testing %d usec absolute timer...\n", time
);
75 printf("Testing %d msec absolute timer...\n", time
);
79 printf("Failure: scale 0x%x not recognized.\n", scale
);
83 expected
= time
* timescale
;
84 deadline
= nowus
/ timescale
+ time
;
86 /* deadlines in the past should fire immediately */
90 EV_SET64(&kev
, 1, EVFILT_TIMER
, EV_ADD
,
91 NOTE_ABSOLUTE
| scale
, deadline
, 0,0,0);
92 ret
= do_simple_kevent(&kev
, expected
);
101 test_oneshot_kevent(int time
, int scale
)
104 uint64_t expected
= 0;
105 struct kevent64_s kev
;
109 printf("Testing %d sec interval timer...\n", time
);
110 expected
= time
* (1000 * 1000);
113 printf("Testing %d usec interval timer...\n", time
);
117 printf("Testing %d nsec interval timer...\n", time
);
118 expected
= time
/ 1000;
121 printf("Testing %d msec interval timer...\n", time
);
122 expected
= time
* 1000;
125 printf("Failure: scale 0x%x not recognized.\n", scale
);
129 /* deadlines in the past should fire immediately */
133 EV_SET64(&kev
, 2, EVFILT_TIMER
, EV_ADD
| EV_ONESHOT
, scale
, time
,
135 ret
= do_simple_kevent(&kev
, expected
);
145 test_repeating_kevent(int usec
)
147 struct kevent64_s kev
;
148 int expected_pops
, ret
;
150 expected_pops
= 1000 * 1000 / usec
;
151 printf("Testing repeating kevent for %d pops in a second...\n",
154 EV_SET64(&kev
, 3, EVFILT_TIMER
, EV_ADD
, NOTE_USECONDS
, usec
, 0, 0, 0);
155 ret
= kevent64(kq
, &kev
, 1, NULL
, 0, 0, NULL
);
157 printf("\tfailure: kevent64 returned %d\n", ret
);
164 ret
= kevent64(kq
, NULL
, 0, &kev
, 1, 0, NULL
);
165 if (ret
!= 1 || (kev
.flags
& EV_ERROR
)) {
166 printf("\tfailure: kevent64 returned %d\n", ret
);
171 /* check how many times the timer fired: within 5%? */
172 if (kev
.data
> expected_pops
+ (expected_pops
/ 20) ||
173 kev
.data
< expected_pops
- (expected_pops
/ 20)) {
174 printf("\tfailure: saw %lld pops.\n", kev
.data
);
177 printf("\tsuccess: saw %lld pops.\n", kev
.data
);
181 EV_SET64(&kev
, 3, EVFILT_TIMER
, EV_DELETE
, 0, 0, 0, 0, 0);
182 ret
= kevent64(kq
, &kev
, 1, NULL
, 0, 0, NULL
);
184 printf("\tfailed to stop repeating timer: %d\n", ret
);
188 test_updated_kevent(int first
, int second
)
190 struct kevent64_s kev
;
193 printf("Testing update from %d to %d msecs...\n", first
, second
);
195 EV_SET64(&kev
, 4, EVFILT_TIMER
, EV_ADD
|EV_ONESHOT
, 0, first
, 0, 0, 0);
196 ret
= kevent64(kq
, &kev
, 1, NULL
, 0, 0, NULL
);
198 printf("\tfailure: initial kevent returned %d\n", ret
);
203 EV_SET64(&kev
, 4, EVFILT_TIMER
, EV_ONESHOT
, 0, second
, 0, 0, 0);
206 ret
= do_simple_kevent(&kev
, second
* 1000);
217 struct kevent64_s kev
;
218 uint64_t nowms
, deadline
;
225 test_absolute_kevent(100, 0);
226 test_absolute_kevent(200, 0);
227 test_absolute_kevent(300, 0);
228 test_absolute_kevent(1000, 0);
229 test_absolute_kevent(500, NOTE_USECONDS
);
230 test_absolute_kevent(100, NOTE_USECONDS
);
231 test_absolute_kevent(5, NOTE_SECONDS
);
232 test_absolute_kevent(-1000, 0);
234 test_oneshot_kevent(1, NOTE_SECONDS
);
235 test_oneshot_kevent(10, 0);
236 test_oneshot_kevent(200, NOTE_USECONDS
);
237 test_oneshot_kevent(300000, NOTE_NSECONDS
);
238 test_oneshot_kevent(-1, NOTE_SECONDS
);
240 test_repeating_kevent(100 * 1000);
241 test_repeating_kevent(5 * 1000);
242 test_repeating_kevent(200);
243 test_repeating_kevent(50);
244 test_repeating_kevent(10);
246 test_updated_kevent(1000, 2000);
247 test_updated_kevent(2000, 1000);
248 test_updated_kevent(1000, -1);
250 printf("\nFinished: %d tests passed, %d failed.\n", passed
, failed
);