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 relative timers.
12 *
13 * For this test, signal SIGTOTEST will be used, clock CLOCK_REALTIME
14 * will be used.
15 */
16
17#include <time.h>
18#include <signal.h>
19#include <stdio.h>
20#include <unistd.h>
21#include <stdlib.h>
22#include "posixtest.h"
23
24#define SIGTOTEST SIGALRM
25#define TIMERVALUESEC 2
26#define TIMERINTERVALSEC 5
27#define INCREMENT 1
28#define ACCEPTABLEDELTA 1
29
30#define NUMTESTS 6
31
32static int timeroffsets[NUMTESTS][2] = { {0, 30000000}, {1, 0},
33					{1, 30000000}, {2, 0},
34					{1, 5000}, {1, 5} };
35
36int main(int argc, char *argv[])
37{
38	struct sigevent ev;
39	timer_t tid;
40	struct itimerspec its;
41	struct timespec tsbefore, tsafter;
42	sigset_t set;
43	int sig;
44	int i;
45	int failure = 0;
46	unsigned long totalnsecs, testnsecs; // so long was we are < 2.1 seconds, we should be safe
47
48	/*
49	 * set up signal set containing SIGTOTEST that will be used
50	 * in call to sigwait immediately after timer is set
51	 */
52
53	if (sigemptyset(&set) == -1 ) {
54		perror("sigemptyset() failed\n");
55		return PTS_UNRESOLVED;
56	}
57
58	if (sigaddset(&set, SIGTOTEST) == -1) {
59		perror("sigaddset() failed\n");
60		return PTS_UNRESOLVED;
61	}
62
63        if (sigprocmask (SIG_BLOCK, &set, NULL) == -1) {
64                perror("sigprocmask() failed\n");
65                return PTS_UNRESOLVED;
66        }
67
68	/*
69	 * set up timer to perform action SIGTOTEST on expiration
70	 */
71	ev.sigev_notify = SIGEV_SIGNAL;
72	ev.sigev_signo = SIGTOTEST;
73
74	if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
75		perror("timer_create() did not return success\n");
76		return PTS_UNRESOLVED;
77	}
78
79	for (i = 0; i < NUMTESTS; i++) {
80		its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0;
81		its.it_value.tv_sec = timeroffsets[i][0];
82		its.it_value.tv_nsec = timeroffsets[i][1];
83
84		printf("Test for value %d sec %d nsec\n",
85				(int) its.it_value.tv_sec,
86				(int) its.it_value.tv_nsec);
87
88		if (clock_gettime(CLOCK_REALTIME, &tsbefore) != 0) {
89			perror("clock_gettime() did not return success\n");
90			return PTS_UNRESOLVED;
91		}
92
93		if (timer_settime(tid, 0, &its, NULL) != 0) {
94			perror("timer_settime() did not return success\n");
95			return PTS_UNRESOLVED;
96		}
97
98		if (sigwait(&set, &sig) == -1) {
99			perror("sigwait() failed\n");
100			return PTS_UNRESOLVED;
101		}
102
103		if (clock_gettime(CLOCK_REALTIME, &tsafter) != 0) {
104			perror("clock_gettime() did not return success\n");
105			return PTS_UNRESOLVED;
106		}
107
108		totalnsecs = (unsigned long) (tsafter.tv_sec-tsbefore.tv_sec)*
109					1000000000 +
110					(tsafter.tv_nsec-tsbefore.tv_nsec);
111		testnsecs = (unsigned long) its.it_value.tv_sec*1000000000 +
112					its.it_value.tv_nsec;
113		printf("total %lu test %lu\n", totalnsecs, testnsecs);
114		if (totalnsecs < testnsecs) {
115			printf("FAIL:  Expired %ld < %ld\n", totalnsecs,
116							testnsecs);
117			failure = 1;
118		}
119	}
120
121	if (timer_delete(tid) != 0) {
122		perror("timer_delete() did not return success\n");
123		return PTS_UNRESOLVED;
124	}
125
126	if (failure) {
127		printf("timer_settime() failed on at least one value\n");
128		return PTS_FAIL;
129	} else {
130		printf("Test PASSED\n");
131		return PTS_PASS;
132	}
133}
134