• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2005
3  * Copyright (c) Wipro Technologies Ltd, 2005.  All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  * AUTHORS:
18  *    Prashant P Yendigeri <prashant.yendigeri@wipro.com>
19  *    Robbie Williamson <robbiew@us.ibm.com>
20  *
21  * DESCRIPTION
22  *      This is a Phase I test for the pselect01(2) system call.
23  *      It is intended to provide a limited exposure of the system call.
24  *
25  **********************************************************/
26 
27 #include <stdio.h>
28 #include <fcntl.h>
29 #include <sys/select.h>
30 #include <sys/time.h>
31 #include <sys/types.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include <stdint.h>
36 
37 #include "test.h"
38 #include "safe_macros.h"
39 
40 static void setup(void);
41 static void cleanup(void);
42 
43 TCID_DEFINE(pselect01);
44 int TST_TOTAL = 9;
45 
46 #define FILENAME "pselect01_test"
47 #define LOOP_COUNT 4
48 
49 static int fd;
50 
pselect_verify(void)51 static void pselect_verify(void)
52 {
53 	fd_set readfds;
54 	struct timespec tv, tv_start, tv_end;
55 	long real_nsec, total_nsec;
56 	double real_sec;
57 	int total_sec, retval;
58 	FD_ZERO(&readfds);
59 	FD_SET(fd, &readfds);
60 	tv.tv_sec = 0;
61 	tv.tv_nsec = 0;
62 
63 	retval = pselect(fd, &readfds, 0, 0, &tv, NULL);
64 	if (retval >= 0)
65 		tst_resm(TPASS, "pselect() succeeded retval=%i", retval);
66 	else
67 		tst_resm(TFAIL | TERRNO, "pselect() failed unexpectedly");
68 
69 	for (total_sec = 1; total_sec <= LOOP_COUNT; total_sec++) {
70 		FD_ZERO(&readfds);
71 		FD_SET(0, &readfds);
72 
73 		tv.tv_sec = total_sec;
74 		tv.tv_nsec = 0;
75 
76 		tst_resm(TINFO,
77 			 "Testing basic pselect sanity,Sleeping for %jd secs",
78 			 (intmax_t) tv.tv_sec);
79 		clock_gettime(CLOCK_MONOTONIC, &tv_start);
80 		pselect(0, &readfds, NULL, NULL, &tv, NULL);
81 		clock_gettime(CLOCK_MONOTONIC, &tv_end);
82 
83 		real_sec = (0.5 + (tv_end.tv_sec - tv_start.tv_sec +
84 				   1e-9 * (tv_end.tv_nsec - tv_start.tv_nsec)));
85 		if (abs(real_sec - total_sec) < 0.2 * total_sec)
86 			tst_resm(TPASS, "Sleep time was correct "
87 				 "(%lf/%d < 20 %%)", real_sec, total_sec);
88 		else
89 			tst_resm(TFAIL, "Sleep time was incorrect (%d/%lf "
90 				 ">= 20%%)", total_sec, real_sec);
91 	}
92 
93 #ifdef DEBUG
94 	tst_resm(TINFO, "Now checking nsec sleep precision");
95 #endif
96 	for (total_nsec = 1e8; total_nsec <= LOOP_COUNT * 1e8;
97 	     total_nsec += 1e8) {
98 		FD_ZERO(&readfds);
99 		FD_SET(0, &readfds);
100 
101 		tv.tv_sec = 0;
102 		tv.tv_nsec = total_nsec;
103 
104 		tst_resm(TINFO,
105 			 "Testing basic pselect sanity,Sleeping for %ld nano secs",
106 			 tv.tv_nsec);
107 		clock_gettime(CLOCK_MONOTONIC, &tv_start);
108 		pselect(0, &readfds, NULL, NULL, &tv, NULL);
109 		clock_gettime(CLOCK_MONOTONIC, &tv_end);
110 
111 		real_nsec = (tv_end.tv_sec - tv_start.tv_sec) * 1e9 +
112 		    tv_end.tv_nsec - tv_start.tv_nsec;
113 
114 		/* allow 20% error */
115 		if (abs(real_nsec - tv.tv_nsec) < 0.2 * total_nsec) {
116 			tst_resm(TPASS, "Sleep time was correct");
117 		} else {
118 			tst_resm(TWARN,
119 				 "This test could fail if the system was under load");
120 			tst_resm(TWARN,
121 				 "due to the limitation of the way it calculates the");
122 			tst_resm(TWARN, "system call execution time.");
123 			tst_resm(TFAIL,
124 				 "Sleep time was incorrect:%ld nsec vs expected %ld nsec",
125 				 real_nsec, total_nsec);
126 		}
127 	}
128 }
129 
main(int argc,char * argv[])130 int main(int argc, char *argv[])
131 {
132 	int lc;
133 
134 	tst_parse_opts(argc, argv, NULL, NULL);
135 
136 	setup();
137 
138 	for (lc = 0; TEST_LOOPING(lc); lc++) {
139 		tst_count = 0;
140 		pselect_verify();
141 	}
142 
143 	cleanup();
144 	tst_exit();
145 }
146 
setup(void)147 static void setup(void)
148 {
149 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
150 	tst_timer_check(CLOCK_MONOTONIC);
151 	tst_tmpdir();
152 
153 	fd = SAFE_OPEN(cleanup, FILENAME, O_CREAT | O_RDWR, 0777);
154 
155 	TEST_PAUSE;
156 }
157 
cleanup(void)158 static void cleanup(void)
159 {
160 	if (fd && close(fd))
161 		tst_resm(TWARN | TERRNO, "close() failed");
162 
163 	tst_rmdir();
164 }
165