• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
3  *
4  * This program is free software;  you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  * the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program;  if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * Check that select() timeouts correctly.
21  */
22 #include <unistd.h>
23 #include <errno.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <fcntl.h>
27 
28 #include "test.h"
29 #include "safe_macros.h"
30 
31 char *TCID = "select04";
32 int TST_TOTAL = 1;
33 
34 static char *opt_sleep_us;
35 
36 static option_t opts[] = {
37 	{"s:", NULL, &opt_sleep_us},
38 	{NULL, NULL, NULL},
39 };
40 
41 static void help(void);
42 static void setup(void);
43 static void cleanup(void);
44 
45 static int fds[2];
46 
main(int ac,char ** av)47 int main(int ac, char **av)
48 {
49 	int lc, treshold;
50 	long long elapsed_us, sleep_us = 100000;
51 	struct timeval timeout;
52 	fd_set sfds;
53 
54 	tst_parse_opts(ac, av, opts, help);
55 
56 	if (opt_sleep_us) {
57 		sleep_us = atoll(opt_sleep_us);
58 
59 		if (sleep_us == 0) {
60 			tst_brkm(TBROK, NULL, "Invalid timeout '%s'",
61 			         opt_sleep_us);
62 		}
63 	}
64 
65 	treshold = sleep_us / 100 + 20000;
66 
67 	setup();
68 
69 	FD_ZERO(&sfds);
70 
71 	for (lc = 0; TEST_LOOPING(lc); lc++) {
72 		FD_SET(fds[0], &sfds);
73 		timeout = tst_us_to_timeval(sleep_us);
74 
75 		tst_timer_start(CLOCK_MONOTONIC);
76 		TEST(select(1, &sfds, NULL, NULL, &timeout));
77 		tst_timer_stop();
78 
79 		if (TEST_RETURN != 0) {
80 			tst_resm(TFAIL, "select() haven't timeouted ret=%li",
81 				 TEST_RETURN);
82 			continue;
83 		}
84 
85 		elapsed_us = tst_timer_elapsed_us();
86 
87 		if (elapsed_us < sleep_us) {
88 			tst_resm(TFAIL,
89 			         "select() woken up too early %llius, expected %llius",
90 				 elapsed_us, sleep_us);
91 			continue;
92 		}
93 
94 		if (elapsed_us - sleep_us > treshold) {
95 			tst_resm(TFAIL,
96 			         "select() slept too long %llius, expected %llius, threshold %i",
97 				 elapsed_us, sleep_us, treshold);
98 			continue;
99 		}
100 
101 		tst_resm(TPASS, "select() slept %llius, expected %llius, treshold %i",
102 		         elapsed_us, sleep_us, treshold);
103 	}
104 
105 	cleanup();
106 	tst_exit();
107 }
108 
setup(void)109 static void setup(void)
110 {
111 	tst_timer_check(CLOCK_MONOTONIC);
112 
113 	SAFE_PIPE(NULL, fds);
114 }
115 
cleanup(void)116 static void cleanup(void)
117 {
118 	if (close(fds[0]))
119 		tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
120 
121 	if (close(fds[1]))
122 		tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
123 }
124 
help(void)125 static void help(void)
126 {
127 	printf("  -s      select() timeout lenght in us\n");
128 }
129