blob: db3b80c7cf2592827884975d0a585ed1c62e1a18 [file] [log] [blame]
subrata_modakaf2c9ef2008-06-03 06:54:12 +00001/*
2 * timerfd() test by Davide Libenzi (test app for timerfd)
3 * Copyright (C) 2007 Davide Libenzi
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Davide Libenzi <davidel@xmailserver.org>
20 *
21 *
22 * $ gcc -o timerfd-test2 timerfd-test2.c -lrt
23 *
24 * NAME
25 * timerfd01.c
26 * HISTORY
27 * 28/05/2008 Initial contribution by Davide Libenzi <davidel@xmailserver.org>
28 * 28/05/2008 Integrated to LTP by Subrata Modak <subrata@linux.vnet.ibm.com>
29 */
30
31#define _GNU_SOURCE
32#include <sys/syscall.h>
33#include <sys/types.h>
34#include <sys/signal.h>
35#include <sys/time.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <unistd.h>
40#include <signal.h>
41#include <poll.h>
42#include <fcntl.h>
43#include <time.h>
44#include <errno.h>
45#include "test.h"
46#include "usctest.h"
47#include "linux_syscall_numbers.h"
48
subrata_modak24fc2132008-11-11 05:57:38 +000049#define cleanup tst_exit
50
subrata_modak56207ce2009-03-23 13:35:39 +000051char *TCID = "timerfd01"; /* Test program identifier */
subrata_modakaf2c9ef2008-06-03 06:54:12 +000052
53/*
54 * This were good at the time of 2.6.23-rc7 ...
subrata_modakea012ad2008-10-21 07:08:23 +000055 *
56 * #ifdef __NR_timerfd
57 *
58 * ... but is not now with 2.6.25
subrata_modakaf2c9ef2008-06-03 06:54:12 +000059 */
subrata_modakea012ad2008-10-21 07:08:23 +000060#ifdef __NR_timerfd_create
subrata_modakaf2c9ef2008-06-03 06:54:12 +000061
62/* Definitions from include/linux/timerfd.h */
63#define TFD_TIMER_ABSTIME (1 << 0)
64
subrata_modakaf2c9ef2008-06-03 06:54:12 +000065struct tmr_type {
66 int id;
67 char const *name;
68};
69
subrata_modak56207ce2009-03-23 13:35:39 +000070unsigned long long getustime(int clockid)
71{
subrata_modakaf2c9ef2008-06-03 06:54:12 +000072 struct timespec tp;
73
74 if (clock_gettime((clockid_t) clockid, &tp)) {
75 perror("clock_gettime");
76 return 0;
77 }
78
79 return 1000000ULL * tp.tv_sec + tp.tv_nsec / 1000;
80}
81
subrata_modak56207ce2009-03-23 13:35:39 +000082void set_timespec(struct timespec *tmr, unsigned long long ustime)
83{
subrata_modakaf2c9ef2008-06-03 06:54:12 +000084
85 tmr->tv_sec = (time_t) (ustime / 1000000ULL);
subrata_modak56207ce2009-03-23 13:35:39 +000086 tmr->tv_nsec = (long)(1000ULL * (ustime % 1000000ULL));
subrata_modakaf2c9ef2008-06-03 06:54:12 +000087}
88
subrata_modak56207ce2009-03-23 13:35:39 +000089int timerfd_create(int clockid, int flags)
90{
subrata_modakaf2c9ef2008-06-03 06:54:12 +000091
Jan Stancek359980f2013-02-15 10:16:05 +010092 return ltp_syscall(__NR_timerfd_create, clockid, flags);
subrata_modakaf2c9ef2008-06-03 06:54:12 +000093}
94
95int timerfd_settime(int ufc, int flags, const struct itimerspec *utmr,
subrata_modak56207ce2009-03-23 13:35:39 +000096 struct itimerspec *otmr)
97{
subrata_modakaf2c9ef2008-06-03 06:54:12 +000098
Jan Stancek359980f2013-02-15 10:16:05 +010099 return ltp_syscall(__NR_timerfd_settime, ufc, flags, utmr, otmr);
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000100}
101
subrata_modak56207ce2009-03-23 13:35:39 +0000102int timerfd_gettime(int ufc, struct itimerspec *otmr)
103{
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000104
Jan Stancek359980f2013-02-15 10:16:05 +0100105 return ltp_syscall(__NR_timerfd_gettime, ufc, otmr);
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000106}
107
subrata_modak56207ce2009-03-23 13:35:39 +0000108long waittmr(int tfd, int timeo)
109{
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000110 u_int64_t ticks;
111 struct pollfd pfd;
112
113 pfd.fd = tfd;
114 pfd.events = POLLIN;
115 pfd.revents = 0;
116 if (poll(&pfd, 1, timeo) < 0) {
117 perror("poll");
118 return -1;
119 }
120 if ((pfd.revents & POLLIN) == 0) {
121 fprintf(stdout, "no ticks happened\n");
122 return -1;
123 }
124 if (read(tfd, &ticks, sizeof(ticks)) != sizeof(ticks)) {
125 perror("timerfd read");
126 return -1;
127 }
128
129 return ticks;
130}
131
132int TST_TOTAL = 3;
133
subrata_modak56207ce2009-03-23 13:35:39 +0000134int main(int ac, char **av)
135{
subrata_modak424f2792008-11-11 04:55:32 +0000136 int i, tfd;
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000137 long ticks;
138 unsigned long long tnow, ttmr;
139 u_int64_t uticks;
140 struct itimerspec tmr;
141 struct tmr_type clks[] = {
subrata_modak56207ce2009-03-23 13:35:39 +0000142 {CLOCK_MONOTONIC, "CLOCK MONOTONIC"},
143 {CLOCK_REALTIME, "CLOCK REALTIME"},
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000144 };
145
subrata_modak56207ce2009-03-23 13:35:39 +0000146 if ((tst_kvercmp(2, 6, 25)) < 0) {
147 tst_resm(TCONF, "This test can only run on kernels that are ");
148 tst_resm(TCONF, "2.6.25 and higher");
149 exit(0);
150 }
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000151
152 for (i = 0; i < sizeof(clks) / sizeof(clks[0]); i++) {
subrata_modak56207ce2009-03-23 13:35:39 +0000153 fprintf(stdout,
154 "\n\n---------------------------------------\n");
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000155 fprintf(stdout, "| testing %s\n", clks[i].name);
156 fprintf(stdout, "---------------------------------------\n\n");
157
158 fprintf(stdout, "relative timer test (at 500 ms) ...\n");
159 set_timespec(&tmr.it_value, 500 * 1000);
160 set_timespec(&tmr.it_interval, 0);
161 tnow = getustime(clks[i].id);
162 if ((tfd = timerfd_create(clks[i].id, 0)) == -1) {
163 perror("timerfd");
164 return 1;
165 }
166 fprintf(stdout, "timerfd = %d\n", tfd);
167
168 if (timerfd_settime(tfd, 0, &tmr, NULL)) {
169 perror("timerfd_settime");
170 return 1;
171 }
172
173 fprintf(stdout, "wating timer ...\n");
174 ticks = waittmr(tfd, -1);
175 ttmr = getustime(clks[i].id);
176 if (ticks <= 0)
177 fprintf(stdout, "whooops! no timer showed up!\n");
178 else
179 fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
180 ticks, (ttmr - tnow) / 1000);
181
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000182 fprintf(stdout, "absolute timer test (at 500 ms) ...\n");
183 tnow = getustime(clks[i].id);
184 set_timespec(&tmr.it_value, tnow + 500 * 1000);
185 set_timespec(&tmr.it_interval, 0);
186 if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tmr, NULL)) {
187 perror("timerfd_settime");
188 return 1;
189 }
190
191 fprintf(stdout, "wating timer ...\n");
192 ticks = waittmr(tfd, -1);
193 ttmr = getustime(clks[i].id);
194 if (ticks <= 0)
195 fprintf(stdout, "whooops! no timer showed up!\n");
196 else
197 fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
198 ticks, (ttmr - tnow) / 1000);
199
200 fprintf(stdout, "sequential timer test (100 ms clock) ...\n");
201 tnow = getustime(clks[i].id);
202 set_timespec(&tmr.it_value, tnow + 100 * 1000);
203 set_timespec(&tmr.it_interval, 100 * 1000);
204 if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tmr, NULL)) {
205 perror("timerfd_settime");
206 return 1;
207 }
208
209 fprintf(stdout, "sleeping 1 second ...\n");
210 sleep(1);
211 if (timerfd_gettime(tfd, &tmr)) {
212 perror("timerfd_gettime");
213 return 1;
214 }
215 fprintf(stdout, "timerfd_gettime returned:\n"
216 "\tit_value = { %ld, %ld } it_interval = { %ld, %ld }\n",
subrata_modak56207ce2009-03-23 13:35:39 +0000217 (long)tmr.it_value.tv_sec, (long)tmr.it_value.tv_nsec,
218 (long)tmr.it_interval.tv_sec,
219 (long)tmr.it_interval.tv_nsec);
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000220 fprintf(stdout, "sleeping 1 second ...\n");
221 sleep(1);
222
223 fprintf(stdout, "wating timer ...\n");
224 ticks = waittmr(tfd, -1);
225 ttmr = getustime(clks[i].id);
226 if (ticks <= 0)
227 fprintf(stdout, "whooops! no timer showed up!\n");
228 else
229 fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
230 ticks, (ttmr - tnow) / 1000);
231
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000232 fprintf(stdout, "O_NONBLOCK test ...\n");
233 tnow = getustime(clks[i].id);
234 set_timespec(&tmr.it_value, 100 * 1000);
235 set_timespec(&tmr.it_interval, 0);
236 if (timerfd_settime(tfd, 0, &tmr, NULL)) {
237 perror("timerfd_settime");
238 return 1;
239 }
240 fprintf(stdout, "timerfd = %d\n", tfd);
241
242 fprintf(stdout, "wating timer (flush the single tick) ...\n");
243 ticks = waittmr(tfd, -1);
244 ttmr = getustime(clks[i].id);
245 if (ticks <= 0)
246 fprintf(stdout, "whooops! no timer showed up!\n");
247 else
248 fprintf(stdout, "got timer ticks (%ld) after %llu ms\n",
249 ticks, (ttmr - tnow) / 1000);
250
251 fcntl(tfd, F_SETFL, fcntl(tfd, F_GETFL, 0) | O_NONBLOCK);
252
253 if (read(tfd, &uticks, sizeof(uticks)) > 0)
subrata_modak56207ce2009-03-23 13:35:39 +0000254 fprintf(stdout,
255 "whooops! timer ticks not zero when should have been\n");
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000256 else if (errno != EAGAIN)
subrata_modak56207ce2009-03-23 13:35:39 +0000257 fprintf(stdout,
258 "whooops! bad errno value (%d = '%s')!\n",
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000259 errno, strerror(errno));
260 else
261 fprintf(stdout, "success\n");
262
263 fcntl(tfd, F_SETFL, fcntl(tfd, F_GETFL, 0) & ~O_NONBLOCK);
264
265 close(tfd);
266 }
267
Garrett Cooper2c282152010-12-16 00:55:50 -0800268 tst_exit();
subrata_modakaf2c9ef2008-06-03 06:54:12 +0000269}
270
subrata_modaka649d522008-06-04 10:30:57 +0000271#else
subrata_modak56207ce2009-03-23 13:35:39 +0000272int TST_TOTAL = 0; /* Total number of test cases. */
subrata_modaka649d522008-06-04 10:30:57 +0000273
subrata_modak56207ce2009-03-23 13:35:39 +0000274int main()
275{
subrata_modaka649d522008-06-04 10:30:57 +0000276
subrata_modak23ddcbc2008-06-28 19:16:04 +0000277 tst_resm(TCONF, "This test needs a kernel that has timerfd syscall.");
Garrett Cooper2c282152010-12-16 00:55:50 -0800278 tst_exit();
subrata_modaka649d522008-06-04 10:30:57 +0000279}
Chris Dearmanec6edca2012-10-17 19:54:01 -0700280#endif