blob: 24bb61c8ca534b349d47bd1c91cc572d7576b677 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
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
13 * the 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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
nstrazfa31d552002-05-14 16:50:06 +000022 * times03.c
plars865695b2001-08-27 22:15:12 +000023 *
24 * DESCRIPTION
25 * Testcase to check the basic functionality of the times() system call.
26 *
27 * ALGORITHM
28 * This testcase checks the values that times(2) system call returns.
29 * Start a process, and spend some CPU time by performing a spin in
30 * a for-loop. Then use the times() system call, to determine the
31 * cpu time/sleep time, and other statistics.
32 *
33 * USAGE: <for command-line>
nstrazfa31d552002-05-14 16:50:06 +000034 * times03 [-c n] [-f] [-P x] [-t]
plars865695b2001-08-27 22:15:12 +000035 * where, -c n : Run n copies concurrently.
36 * -f : Turn off functionality Testing.
37 * -P x : Pause for x seconds between iterations.
38 * -t : Turn on syscall timing.
39 *
40 * History
41 * 07/2001 John George
42 * -Ported
43 *
44 * Restrictions
45 * NONE
46 */
47
48#include <sys/types.h>
49#include <sys/times.h>
50#include <errno.h>
51#include <wait.h>
plars74948ad2002-11-14 16:16:14 +000052#include <time.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080053#include "test.h"
subrata_modak551313c2007-08-06 10:53:51 +000054#include <signal.h>
subrata_modak923b23f2009-11-02 13:57:16 +000055#include <stdint.h>
plars865695b2001-08-27 22:15:12 +000056
nstrazfa31d552002-05-14 16:50:06 +000057char *TCID = "times03";
plars865695b2001-08-27 22:15:12 +000058int TST_TOTAL = 1;
Wanlong Gao354ebb42012-12-07 10:10:04 +080059
subrata_modak0c2e2e22008-01-28 11:33:15 +000060volatile int timeout; /* Did we timeout in alarm() ? */
subrata_modak551313c2007-08-06 10:53:51 +000061
62void work(void);
subrata_modak56207ce2009-03-23 13:35:39 +000063void sighandler(int signal, siginfo_t * info, void *uc);
plars865695b2001-08-27 22:15:12 +000064
65void setup(void);
66void cleanup(void);
67
plars74948ad2002-11-14 16:16:14 +000068int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000069{
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020070 const char *msg;
plars865695b2001-08-27 22:15:12 +000071
72 struct tms buf1, buf2;
73 time_t start_time, end_time;
Garrett Cooperf1d2a632010-12-19 08:23:06 -080074 int pid2, status;
subrata_modak551313c2007-08-06 10:53:51 +000075 struct sigaction sa;
plars865695b2001-08-27 22:15:12 +000076
Garrett Cooperf1d2a632010-12-19 08:23:06 -080077 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080078 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080079
plars865695b2001-08-27 22:15:12 +000080 setup();
81
subrata_modak4bb656a2009-02-26 12:02:09 +000082 /*
subrata_modak551313c2007-08-06 10:53:51 +000083 * We spend time in userspace using the following mechanism :
84 * Setup an alarm() for 3 secs and do some simple loop operations
subrata_modak4bb656a2009-02-26 12:02:09 +000085 * until we get the signal. This makes the test independent of
subrata_modak551313c2007-08-06 10:53:51 +000086 * processor speed.
87 */
88 sa.sa_sigaction = sighandler;
89 sigemptyset(&sa.sa_mask);
90 sa.sa_flags = SA_SIGINFO;
subrata_modakbdbaec52009-02-26 12:14:51 +000091
Garrett Cooperf1d2a632010-12-19 08:23:06 -080092 if (sigaction(SIGALRM, &sa, NULL) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +080093 tst_brkm(TBROK | TERRNO, cleanup, "Sigaction failed !\n");
subrata_modakbdbaec52009-02-26 12:14:51 +000094
subrata_modak551313c2007-08-06 10:53:51 +000095 timeout = 0;
96 alarm(3);
plars865695b2001-08-27 22:15:12 +000097
subrata_modak551313c2007-08-06 10:53:51 +000098 work();
99
plars865695b2001-08-27 22:15:12 +0000100 /*
subrata_modak551313c2007-08-06 10:53:51 +0000101 * At least some CPU time must be used in system space. This is
plars865695b2001-08-27 22:15:12 +0000102 * achieved by executing the times(2) call for
103 * atleast 5 secs. This logic makes it independant
104 * of the processor speed.
105 */
106 start_time = time(NULL);
107 for (;;) {
Garrett Cooperf1d2a632010-12-19 08:23:06 -0800108 if (times(&buf1) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800109 tst_resm(TFAIL | TERRNO, "times failed");
plars865695b2001-08-27 22:15:12 +0000110 end_time = time(NULL);
111 if ((end_time - start_time) > 5) {
112 break;
113 }
114 }
Cyril Hrubise38b9612014-06-02 17:20:57 +0200115 if (times(&buf1) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800116 tst_resm(TFAIL | TERRNO, "times failed");
Cyril Hrubise38b9612014-06-02 17:20:57 +0200117 } else {
118 if (buf1.tms_utime == 0)
119 tst_resm(TFAIL, "times report " "0 user time");
120 if (buf1.tms_stime == 0)
121 tst_resm(TFAIL, "times report "
122 "0 system time");
123 if (buf1.tms_cutime != 0)
124 tst_resm(TFAIL, "times report "
125 "%ld child user time",
126 buf1.tms_cutime);
127 if (buf1.tms_cstime != 0)
128 tst_resm(TFAIL,
129 "times report "
130 "%ld child system time",
131 buf1.tms_cstime);
plars865695b2001-08-27 22:15:12 +0000132
Cyril Hrubise38b9612014-06-02 17:20:57 +0200133 pid2 = FORK_OR_VFORK();
134 if (pid2 < 0) {
135 tst_brkm(TFAIL, cleanup, "Fork failed");
136 } else if (pid2 == 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000137
Cyril Hrubise38b9612014-06-02 17:20:57 +0200138 /* Spend some cycles in userspace */
subrata_modak551313c2007-08-06 10:53:51 +0000139
Cyril Hrubise38b9612014-06-02 17:20:57 +0200140 timeout = 0;
141 alarm(3);
subrata_modak551313c2007-08-06 10:53:51 +0000142
Cyril Hrubise38b9612014-06-02 17:20:57 +0200143 work();
subrata_modak551313c2007-08-06 10:53:51 +0000144
Cyril Hrubise38b9612014-06-02 17:20:57 +0200145 /*
146 * Atleast some CPU system ime must be used
147 * even in the child process (thereby
148 * making it independent of the
149 * processor speed). In fact the child
150 * uses twice as much CPU time.
151 */
152 start_time = time(NULL);
153 for (;;) {
154 if (times(&buf2) == -1) {
155 tst_resm(TFAIL,
156 "Call to times "
157 "failed, "
158 "errno = %d", errno);
159 exit(1);
plars865695b2001-08-27 22:15:12 +0000160 }
Cyril Hrubise38b9612014-06-02 17:20:57 +0200161 end_time = time(NULL);
162 if ((end_time - start_time)
163 > 10) {
164 break;
165 }
plars865695b2001-08-27 22:15:12 +0000166 }
Cyril Hrubise38b9612014-06-02 17:20:57 +0200167 exit(0);
168 }
subrata_modak551313c2007-08-06 10:53:51 +0000169
Cyril Hrubise38b9612014-06-02 17:20:57 +0200170 waitpid(pid2, &status, 0);
171 if (WEXITSTATUS(status) != 0) {
172 tst_resm(TFAIL, "Call to times(2) "
173 "failed in child");
174 }
175 if (times(&buf2) == -1) {
Cyril Hrubise38b9612014-06-02 17:20:57 +0200176 tst_resm(TFAIL | TTERRNO, "times failed");
177 }
178 if (buf1.tms_utime > buf2.tms_utime)
179 tst_resm(TFAIL, "Error: parents's "
180 "user time(%ld) before child "
181 "> parent's user time (%ld) "
182 "after child",
183 buf1.tms_utime, buf2.tms_utime);
184 if (buf2.tms_cutime == 0)
185 tst_resm(TFAIL, "times "
186 "report %ld child user "
187 "time should be > than "
188 "zero", buf2.tms_cutime);
189 if (buf2.tms_cstime == 0)
190 tst_resm(TFAIL, "times "
191 "report %ld child system time "
192 "should be > than zero",
193 buf2.tms_cstime);
plars865695b2001-08-27 22:15:12 +0000194 }
Cyril Hrubise38b9612014-06-02 17:20:57 +0200195
plars865695b2001-08-27 22:15:12 +0000196 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800197 tst_exit();
plars865695b2001-08-27 22:15:12 +0000198}
199
200/*
subrata_modak551313c2007-08-06 10:53:51 +0000201 * sighandler
202 * Set the timeout to indicate we timed out in the alarm().
203 */
204
subrata_modak56207ce2009-03-23 13:35:39 +0000205void sighandler(int signal, siginfo_t * info, void *uc)
subrata_modak551313c2007-08-06 10:53:51 +0000206{
subrata_modak4bb656a2009-02-26 12:02:09 +0000207 if (signal == SIGALRM)
subrata_modak551313c2007-08-06 10:53:51 +0000208 timeout = 1;
209 else
subrata_modak56207ce2009-03-23 13:35:39 +0000210 tst_brkm(TBROK, cleanup, "Unexpected signal %d\n", signal);
subrata_modak551313c2007-08-06 10:53:51 +0000211}
212
213/*
214 * work
215 * Do some work in user space, until we get a timeout.
216 */
217
218void work(void)
219{
220 int i, j, k;
221
222 while (!timeout)
subrata_modak56207ce2009-03-23 13:35:39 +0000223 for (i = 0; i < 10000; i++)
224 for (j = 0; j < 100; j++)
subrata_modak551313c2007-08-06 10:53:51 +0000225 k = i * j;
226 timeout = 0;
227}
228
229/*
plars865695b2001-08-27 22:15:12 +0000230 * setup()
231 * performs all ONE TIME setup for this test
232 */
subrata_modak56207ce2009-03-23 13:35:39 +0000233void setup(void)
plars865695b2001-08-27 22:15:12 +0000234{
Garrett Cooper2c282152010-12-16 00:55:50 -0800235
plars865695b2001-08-27 22:15:12 +0000236 tst_sig(FORK, DEF_HANDLER, cleanup);
237
plars865695b2001-08-27 22:15:12 +0000238 /* Pause if that option was specified
239 * TEST_PAUSE contains the code to fork the test with the -c option.
240 */
241 TEST_PAUSE;
242}
243
244/*
245 * cleanup()
246 * performs all ONE TIME cleanup for this test at
247 * completion or premature exit
248 */
subrata_modak56207ce2009-03-23 13:35:39 +0000249void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000250{
plars865695b2001-08-27 22:15:12 +0000251
Wanlong Gao354ebb42012-12-07 10:10:04 +0800252}