1 /*
2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
3  * Created by:  julie.n.fleischer REMOVE-THIS AT intel DOT com
4  * This file is licensed under the GPL license.  For the full content
5  * of this license, see the COPYING file at the top level of this
6  * source tree.
7  *
8  * Test that timer_getoverrun() returns the number of overruns that
9  * have happened due to signals being sent from a timer.  Test with
10  * timer seconds in nanoseconds.
11  *
12  * Steps (testing with just one overrun):
13  * - Block signal SIGCONT (SIGCONT used so test will not terminate)
14  * - Set up a timer to send SIGCONT on expiration with an interval
15  *   of INTERVALNSEC nanoseconds.
16  * - Wait for that timer to expire EXPECTEDIVERRUNS+1 times (wait VALUENSEC +
17  *   (EXPECTEDIVERRUNS)*INTERVALNSEC).
18  * - Call timer_getoverrun() and ensure EXPECTEDOVERRUNS was returned.
19  *   [First signal made it.  All others were overruns.]
20  */
21 
22 #include <signal.h>
23 #include <time.h>
24 #include <unistd.h>
25 #include <stdio.h>
26 #include "posixtest.h"
27 
28 #define VALUENSEC 2000000
29 #define INTERVALNSEC 5000000
30 
31 #define EXPECTEDOVERRUNS 75
32 
main()33 int main()
34 {
35 	sigset_t set;
36 	struct sigevent ev;
37 	timer_t tid;
38 	struct itimerspec its;
39 	struct timespec ts;
40 	int overruns;
41 
42 	if (sigemptyset(&set) != 0) {
43 		perror("sigemptyset() did not return success\n");
44 		return PTS_UNRESOLVED;
45 	}
46 
47 	if (sigaddset(&set, SIGCONT) != 0) {
48 		perror("sigaddset() did not return success\n");
49 		return PTS_UNRESOLVED;
50 	}
51 
52 	if (sigprocmask(SIG_SETMASK, &set, NULL) != 0) {
53 		perror("sigprocmask() did not return success\n");
54 		return PTS_UNRESOLVED;
55 	}
56 
57 	ev.sigev_notify = SIGEV_SIGNAL;
58 	ev.sigev_signo = SIGCONT;
59 
60 	/*
61 	 * create first timer
62 	 */
63 	if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
64 		perror("timer_create() did not return success\n");
65 		return PTS_UNRESOLVED;
66 	}
67 
68 	its.it_interval.tv_sec = 0;
69 	its.it_interval.tv_nsec = INTERVALNSEC;
70 	its.it_value.tv_sec = 0;
71 	its.it_value.tv_nsec = VALUENSEC;
72 
73 	if (timer_settime(tid, 0, &its, NULL) != 0) {
74 		perror("timer_settime() did not return success\n");
75 		return PTS_UNRESOLVED;
76 	}
77 
78 	ts.tv_nsec = VALUENSEC + ((EXPECTEDOVERRUNS)*INTERVALNSEC);
79 	ts.tv_sec = 0;
80 	if (nanosleep(&ts, NULL) != 0) {
81 		perror("nanosleep() did not return success\n");
82 		return PTS_UNRESOLVED;
83 	}
84 
85 	if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) {
86 		perror("sigprocmask() did not return success\n");
87 		return PTS_UNRESOLVED;
88 	}
89 
90 	overruns = timer_getoverrun(tid);
91 	if (overruns > EXPECTEDOVERRUNS - 5) {
92 		printf("Test PASSED\n");
93 		return PTS_PASS;
94 	} else {
95 		printf("FAIL:  %d overruns sent; expected %d\n",
96 				overruns, EXPECTEDOVERRUNS);
97 		return PTS_FAIL;
98 	}
99 }
100