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_settime() uses an absolute clock if TIMER_ABSTIME is
9 * set in flags.
10 *
11 * Uses the same steps as 1-1.c to determine how long the timer lasted.
12 * In order to use an absolute clock, the timer time is determined by:
13 * - Get current time.
14 * - Set the timer to TIMERSEC+current time.
15 * - After the timer goes off, ensure that the timer went off within
16 *   ACCEPTABLEDELTA of TIMERSEC seconds.
17 *
18 * For this test, signal SIGTOTEST will be used, clock CLOCK_REALTIME
19 * will be used.
20 */
21
22#include <time.h>
23#include <signal.h>
24#include <stdio.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include "posixtest.h"
28
29#define SIGTOTEST SIGALRM
30#define TIMERSEC 2
31#define SLEEPDELTA 3
32#define ACCEPTABLEDELTA 1
33
34void handler(int signo)
35{
36	printf("Caught signal\n");
37}
38
39int main(void)
40{
41	struct sigevent ev;
42	struct sigaction act;
43	timer_t tid;
44	struct itimerspec its;
45	struct timespec beforets, ts, tsleft;
46	int flags = 0;
47
48	ev.sigev_notify = SIGEV_SIGNAL;
49	ev.sigev_signo = SIGTOTEST;
50
51	act.sa_handler = handler;
52	act.sa_flags = 0;
53
54	if (sigemptyset(&act.sa_mask) == -1) {
55		perror("Error calling sigemptyset\n");
56		return PTS_UNRESOLVED;
57	}
58	if (sigaction(SIGTOTEST, &act, 0) == -1) {
59		perror("Error calling sigaction\n");
60		return PTS_UNRESOLVED;
61	}
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	if (clock_gettime(CLOCK_REALTIME, &beforets) != 0) {
69		perror("clock_gettime() did not return success\n");
70		return PTS_UNRESOLVED;
71	}
72
73	its.it_interval.tv_sec = 0;
74	its.it_interval.tv_nsec = 0;
75	its.it_value.tv_sec = beforets.tv_sec + TIMERSEC;
76	its.it_value.tv_nsec = beforets.tv_nsec;
77
78	ts.tv_sec = TIMERSEC + SLEEPDELTA;
79	ts.tv_nsec = 0;
80
81	flags |= TIMER_ABSTIME;
82	if (timer_settime(tid, flags, &its, NULL) != 0) {
83		perror("timer_settime() did not return success\n");
84		return PTS_UNRESOLVED;
85	}
86
87	if (nanosleep(&ts, &tsleft) != -1) {
88		perror("nanosleep() not interrupted\n");
89		return PTS_FAIL;
90	}
91
92	if (abs(tsleft.tv_sec - SLEEPDELTA) <= ACCEPTABLEDELTA) {
93		printf("Test PASSED\n");
94		return PTS_PASS;
95	}
96
97	printf("Timer did not last for correct amount of time\n");
98	printf("timer: %d != correct %d\n",
99	       (int)ts.tv_sec - (int)tsleft.tv_sec, TIMERSEC);
100	return PTS_FAIL;
101}
102