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 timers are not allowed to expire before their scheduled
9 * time.
10 *
11 * Test for a variety of timer values on absolute timers.
12 * Steps:
13 * - get time T0
14 * - add offset to T0 to give T1
15 * - set the timer to expire at T1
16 * - wait for the timer to expire
17 * - get time T2
18 * - ensure T2 >= T1
19 *
20 * For this test, signal SIGTOTEST will be used, clock CLOCK_REALTIME
21 * will be used.
22 */
23
24#include <time.h>
25#include <signal.h>
26#include <stdio.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include "posixtest.h"
30
31#define SIGTOTEST SIGALRM
32#define TIMERVALUESEC 2
33#define TIMERINTERVALSEC 5
34#define INCREMENT 1
35#define ACCEPTABLEDELTA 1
36
37#define NUMTESTS 6
38
39static int timeroffsets[NUMTESTS][2] = { {0, 90000000}, {1, 0},
40					{1, 30000000}, {2, 0},
41					{3, 5000}, {4, 5} };
42
43int main(int argc, char *argv[])
44{
45	struct sigevent ev;
46	timer_t tid;
47	struct itimerspec its;
48	struct timespec tsbefore, tsafter;
49	sigset_t set;
50	int sig;
51	int i;
52	int failure = 0;
53	int flags = 0;
54
55	/*
56	 * set up signal set containing SIGTOTEST that will be used
57	 * in call to sigwait immediately after timer is set
58	 */
59
60	if (sigemptyset(&set) == -1 ) {
61		perror("sigemptyset() failed\n");
62		return PTS_UNRESOLVED;
63	}
64
65	if (sigaddset(&set, SIGTOTEST) == -1) {
66		perror("sigaddset() failed\n");
67		return PTS_UNRESOLVED;
68	}
69
70        if (sigprocmask (SIG_BLOCK, &set, NULL) == -1) {
71                perror("sigprocmask() failed\n");
72                return PTS_UNRESOLVED;
73        }
74
75	/*
76	 * set up timer to perform action SIGTOTEST on expiration
77	 */
78	ev.sigev_notify = SIGEV_SIGNAL;
79	ev.sigev_signo = SIGTOTEST;
80
81	if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
82		perror("timer_create() did not return success\n");
83		return PTS_UNRESOLVED;
84	}
85
86	flags |= TIMER_ABSTIME;
87	its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0;
88	for (i = 0; i < NUMTESTS; i++) {
89		if (clock_gettime(CLOCK_REALTIME, &tsbefore) != 0) {
90			perror("clock_gettime() did not return success\n");
91			return PTS_UNRESOLVED;
92		}
93
94		if (tsbefore.tv_nsec + timeroffsets[i][1] < 1000000000) {
95			its.it_value.tv_sec = tsbefore.tv_sec +
96						timeroffsets[i][0];
97			its.it_value.tv_nsec = tsbefore.tv_nsec +
98						timeroffsets[i][1];
99		} else {
100			its.it_value.tv_sec = tsbefore.tv_sec +
101						timeroffsets[i][0] + 1;
102			its.it_value.tv_nsec = tsbefore.tv_nsec +
103						timeroffsets[i][1] -
104						1000000000;
105		}
106
107		printf("Test for value %d sec %d nsec\n",
108				(int) its.it_value.tv_sec,
109				(int) its.it_value.tv_nsec);
110
111		if (timer_settime(tid, flags, &its, NULL) != 0) {
112			perror("timer_settime() did not return success\n");
113			return PTS_UNRESOLVED;
114		}
115
116		if (sigwait(&set, &sig) == -1) {
117			perror("sigwait() failed\n");
118			return PTS_UNRESOLVED;
119		}
120
121		if (clock_gettime(CLOCK_REALTIME, &tsafter) != 0) {
122			perror("clock_gettime() did not return success\n");
123			return PTS_UNRESOLVED;
124		}
125
126		printf("Timer expired %d sec %d nsec\n",
127				(int) tsafter.tv_sec,
128				(int) tsafter.tv_nsec);
129		if (tsafter.tv_sec < its.it_value.tv_sec) {
130			printf("FAIL:  Timer expired %d sec < %d sec\n",
131					(int) tsafter.tv_sec,
132					(int) its.it_value.tv_sec);
133			failure = 1;
134		} else if (tsafter.tv_sec == its.it_value.tv_sec) {
135				if (tsafter.tv_nsec < its.it_value.tv_nsec) {
136			printf("FAIL:  Timer expired %d nsec < %d nsec\n",
137						(int) tsafter.tv_nsec,
138						(int) its.it_value.tv_nsec);
139					failure = 1;
140				}
141			}
142	}
143
144	if (timer_delete(tid) != 0) {
145		perror("timer_delete() did not return success\n");
146		return PTS_UNRESOLVED;
147	}
148
149	if (failure) {
150		printf("timer_settime() failed on at least one value\n");
151		return PTS_FAIL;
152	} else {
153		printf("Test PASSED\n");
154		return PTS_PASS;
155	}
156}
157