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};
36
37int main(void)
38{
39	struct sigevent ev;
40	timer_t tid;
41	struct itimerspec its;
42	struct timespec tsbefore, tsafter;
43	sigset_t set;
44	int sig;
45	int i;
46	int failure = 0;
47	unsigned long totalnsecs, testnsecs;	// so long was we are < 2.1 seconds, we should be safe
48
49	/*
50	 * set up signal set containing SIGTOTEST that will be used
51	 * in call to sigwait immediately after timer is set
52	 */
53
54	if (sigemptyset(&set) == -1) {
55		perror("sigemptyset() failed\n");
56		return PTS_UNRESOLVED;
57	}
58
59	if (sigaddset(&set, SIGTOTEST) == -1) {
60		perror("sigaddset() failed\n");
61		return PTS_UNRESOLVED;
62	}
63
64	if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
65		perror("sigprocmask() failed\n");
66		return PTS_UNRESOLVED;
67	}
68
69	/*
70	 * set up timer to perform action SIGTOTEST on expiration
71	 */
72	ev.sigev_notify = SIGEV_SIGNAL;
73	ev.sigev_signo = SIGTOTEST;
74
75	if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) {
76		perror("timer_create() did not return success\n");
77		return PTS_UNRESOLVED;
78	}
79
80	for (i = 0; i < NUMTESTS; i++) {
81		its.it_interval.tv_sec = 0;
82		its.it_interval.tv_nsec = 0;
83		its.it_value.tv_sec = timeroffsets[i][0];
84		its.it_value.tv_nsec = timeroffsets[i][1];
85
86		printf("Test for value %d sec %d nsec\n",
87		       (int)its.it_value.tv_sec, (int)its.it_value.tv_nsec);
88
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 (timer_settime(tid, 0, &its, NULL) != 0) {
95			perror("timer_settime() did not return success\n");
96			return PTS_UNRESOLVED;
97		}
98
99		if (sigwait(&set, &sig) == -1) {
100			perror("sigwait() failed\n");
101			return PTS_UNRESOLVED;
102		}
103
104		if (clock_gettime(CLOCK_REALTIME, &tsafter) != 0) {
105			perror("clock_gettime() did not return success\n");
106			return PTS_UNRESOLVED;
107		}
108
109		totalnsecs = (unsigned long)(tsafter.tv_sec - tsbefore.tv_sec) *
110		    1000000000 + (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