blob: aaf3849303e4b0aea0decce743f5f5e59dc4b0d5 [file] [log] [blame]
alaffincc2e5552000-07-27 17:13:18 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
Cyril Hrubis2a81c752014-05-27 14:54:09 +02003 * AUTHOR : William Roske/Richard Logan
vapier45a8ba02009-07-20 10:59:32 +00004 *
alaffincc2e5552000-07-27 17:13:18 +00005 * 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.
vapier45a8ba02009-07-20 10:59:32 +00008 *
alaffincc2e5552000-07-27 17:13:18 +00009 * 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.
vapier45a8ba02009-07-20 10:59:32 +000012 *
alaffincc2e5552000-07-27 17:13:18 +000013 * Further, this software is distributed without any warranty that it is
14 * free of the rightful claim of any third person regarding infringement
15 * or the like. Any license provided herein, whether implied or
16 * otherwise, applies only to this software file. Patent licenses, if
17 * any, provided herein do not apply to combinations of this program with
18 * other software, or any other product whatsoever.
vapier45a8ba02009-07-20 10:59:32 +000019 *
alaffincc2e5552000-07-27 17:13:18 +000020 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080021 * with this program; if not, write the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
vapier45a8ba02009-07-20 10:59:32 +000023 *
alaffincc2e5552000-07-27 17:13:18 +000024 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
25 * Mountain View, CA 94043, or:
vapier45a8ba02009-07-20 10:59:32 +000026 *
27 * http://www.sgi.com
28 *
29 * For further information regarding this notice, see:
30 *
alaffincc2e5552000-07-27 17:13:18 +000031 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
32 */
33
Mike Frysinger28606c12010-08-17 17:22:45 -040034#include "config.h"
alaffincc2e5552000-07-27 17:13:18 +000035#include <errno.h>
36#include <stdlib.h>
37#include <string.h>
38#include <sys/param.h>
39#include <sys/signal.h>
40#include <sys/types.h>
41#include <unistd.h>
42#include <sys/time.h>
Cyril Hrubis4d964f62012-03-07 18:02:37 +010043#include <stdint.h>
alaffincc2e5552000-07-27 17:13:18 +000044
alaffincc2e5552000-07-27 17:13:18 +000045#include "test.h"
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020046#include "ltp_priv.h"
alaffincc2e5552000-07-27 17:13:18 +000047#include "usctest.h"
alaffincc2e5552000-07-27 17:13:18 +000048
alaffincc2e5552000-07-27 17:13:18 +000049#ifndef UNIT_TEST
50#define UNIT_TEST 0
51#endif
52
alaffincc2e5552000-07-27 17:13:18 +000053/* The timing information block. */
Wanlong Gao354ebb42012-12-07 10:10:04 +080054struct tblock tblock = { 0, ((long)-1) >> 1, 0, 0 };
alaffincc2e5552000-07-27 17:13:18 +000055
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080056#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +080057extern pid_t spawned_program_pid;
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080058#endif
alaffincc2e5552000-07-27 17:13:18 +000059
60/* Define flags and args for standard options */
Cyril Hrubisd5d39082014-05-27 15:28:09 +020061int STD_FUNCTIONAL_TEST = 1; /* flag indicating to do functional testing code */
62int STD_TIMING_ON = 0; /* flag indicating to print timing stats */
63static int STD_PAUSE = 0; /* flag indicating to pause before actual start, */
Wanlong Gao354ebb42012-12-07 10:10:04 +080064 /* for contention mode */
Cyril Hrubisd5d39082014-05-27 15:28:09 +020065static int STD_INFINITE = 0; /* flag indciating to loop forever */
66int STD_LOOP_COUNT = 1; /* number of iterations */
67int STD_COPIES = 1; /* number of copies */
68int STD_ERRNO_LOG = 0; /* flag indicating to do errno logging */
alaffincc2e5552000-07-27 17:13:18 +000069
Cyril Hrubisd5d39082014-05-27 15:28:09 +020070static float STD_LOOP_DURATION = 0.0; /* duration value in fractional seconds */
71static float STD_LOOP_DELAY = 0.0; /* loop delay value in fractional seconds */
alaffincc2e5552000-07-27 17:13:18 +000072
Cyril Hrubisd5d39082014-05-27 15:28:09 +020073static char **STD_opt_arr = NULL; /* array of option strings */
74static int STD_argind = 1; /* argv index to next argv element */
alaffincc2e5552000-07-27 17:13:18 +000075 /* (first argument) */
76 /* To getopt users, it is like optind */
77
78/*
79 * The following variables are to support system testing additions.
80 */
Wanlong Gao354ebb42012-12-07 10:10:04 +080081static int STD_TP_barrier = 0; /* flag to do barrier in TEST_PAUSE */
alaffincc2e5552000-07-27 17:13:18 +000082 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +080083static int STD_LP_barrier = 0; /* flag to do barrier in TEST_LOOPING */
alaffincc2e5552000-07-27 17:13:18 +000084 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +080085static int STD_TP_shmem_sz = 0; /* shmalloc this many words per pe in TEST_PAUSE */
86static int STD_LD_shmem = 0; /* flag to do shmem_puts and shmem_gets during delay */
87static int STD_LP_shmem = 0; /* flag to do shmem_puts and gets during TEST_LOOPING */
88static int STD_LD_recfun = 0; /* do recressive function calls in loop delay */
89static int STD_LP_recfun = 0; /* do recressive function calls in TEST_LOOPING */
90static int STD_TP_sbrk = 0; /* do sbrk in TEST_PAUSE */
91static int STD_LP_sbrk = 0; /* do sbrk in TEST_LOOPING */
92static char *STD_start_break = 0; /* original sbrk size */
93static int Debug = 0;
alaffincc2e5552000-07-27 17:13:18 +000094
Cyril Hrubisd5d39082014-05-27 15:28:09 +020095static struct std_option_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +080096 char *optstr;
97 char *help;
98 char *flag;
99 char **arg;
nstraz94181082000-08-30 18:43:38 +0000100} std_options[] = {
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200101 {"c:", " -c n Run n copies concurrently\n", NULL, NULL},
102 {"e", " -e Turn on errno logging\n", NULL, NULL},
103 {"f", " -f Turn off functional testing\n", NULL, NULL},
104 {"h", " -h Show this help screen\n", NULL, NULL},
105 {"i:", " -i n Execute test n times\n", NULL, NULL},
106 {"I:", " -I x Execute test for x seconds\n", NULL, NULL},
107 {"p", " -p Pause for SIGUSR1 before starting\n", NULL, NULL},
108 {"P:", " -P x Pause for x seconds between iterations\n", NULL, NULL},
109 {"t", " -t Turn on syscall timing\n", NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000110#ifdef UCLINUX
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200111 {"C:",
112 " -C ARG Run the child process with arguments ARG (for internal use)\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800113 NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000114#endif
Cyril Hrubisd5d39082014-05-27 15:28:09 +0200115 {NULL, NULL, NULL, NULL}
116};
nstraz94181082000-08-30 18:43:38 +0000117
alaffincc2e5552000-07-27 17:13:18 +0000118/*
119 * Structure for usc_recressive_func argument
120 */
121struct usc_bigstack_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800122 char space[4096];
alaffincc2e5552000-07-27 17:13:18 +0000123};
124
Wanlong Gao354ebb42012-12-07 10:10:04 +0800125static struct usc_bigstack_t *STD_bigstack = NULL;
alaffincc2e5552000-07-27 17:13:18 +0000126
alaffincc2e5552000-07-27 17:13:18 +0000127/*
128 * Counter of errnos returned (-e option). Indexed by errno.
129 * Make the array USC_MAX_ERRNO long. That is the first Fortran
130 * Lib errno. No syscall should return an errno that high.
131 */
132int STD_ERRNO_LIST[USC_MAX_ERRNO];
133
134/* define the string length for Mesg and Mesg2 strings */
135#define STRLEN 2048
136
alaffincc2e5552000-07-27 17:13:18 +0000137static char Mesg2[STRLEN]; /* holds possible return string */
138static void usc_recressive_func();
139
140/*
141 * Define bits for options that might have env variable default
142 */
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200143#define OPT_iteration 01
144#define OPT_nofunccheck 02
145#define OPT_duration 04
146#define OPT_delay 010
147#define OPT_copies 020
alaffincc2e5552000-07-27 17:13:18 +0000148
robbiewd34d5812005-07-11 22:28:09 +0000149#ifdef UCLINUX
150/* Allocated and used in self_exec.c: */
151extern char *child_args; /* Arguments to child when -C is used */
152#endif
alaffincc2e5552000-07-27 17:13:18 +0000153
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200154static void print_help(void (*user_help)(void))
155{
156 int i;
157
158 for (i = 0; std_options[i].optstr; ++i) {
159 if (std_options[i].help)
160 printf("%s", std_options[i].help);
161 }
162
163 if (user_help)
164 user_help();
165}
166
alaffincc2e5552000-07-27 17:13:18 +0000167/**********************************************************************
vapier45a8ba02009-07-20 10:59:32 +0000168 * parse_opts:
alaffincc2e5552000-07-27 17:13:18 +0000169 **********************************************************************/
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200170const char *parse_opts(int ac, char **av, const option_t * user_optarr,
171 void (*uhf)(void))
alaffincc2e5552000-07-27 17:13:18 +0000172{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800173 int found; /* flag to indicate that an option specified was */
174 /* found in the user's list */
175 int k; /* scratch integer for returns and short time usage */
176 float ftmp; /* tmp float for parsing env variables */
177 char *ptr; /* used in getting env variables */
178 int options = 0; /* no options specified */
179 int optstrlen, i;
180 char *optionstr;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200181 int opt;
alaffincc2e5552000-07-27 17:13:18 +0000182
Wanlong Gao354ebb42012-12-07 10:10:04 +0800183 /*
184 * If not the first time this function is called, release the old STD_opt_arr
185 * vector.
186 */
alaffincc2e5552000-07-27 17:13:18 +0000187
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800188#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +0800189 spawned_program_pid = getpid();
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800190#endif
191
Wanlong Gao354ebb42012-12-07 10:10:04 +0800192 if (STD_opt_arr != NULL) {
193 free(STD_opt_arr);
194 STD_opt_arr = NULL;
nstraz94181082000-08-30 18:43:38 +0000195 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800196 /* Calculate how much space we need for the option string */
197 optstrlen = 0;
198 for (i = 0; std_options[i].optstr; ++i)
199 optstrlen += strlen(std_options[i].optstr);
200 if (user_optarr)
201 for (i = 0; user_optarr[i].option; ++i) {
202 if (strlen(user_optarr[i].option) > 2)
203 return
204 "parse_opts: ERROR - Only short options are allowed";
205 optstrlen += strlen(user_optarr[i].option);
206 }
207 optstrlen += 1;
alaffincc2e5552000-07-27 17:13:18 +0000208
Wanlong Gao354ebb42012-12-07 10:10:04 +0800209 /* Create the option string for getopt */
210 optionstr = malloc(optstrlen);
211 if (!optionstr)
212 return
213 "parse_opts: ERROR - Could not allocate memory for optionstr";
alaffincc2e5552000-07-27 17:13:18 +0000214
Wanlong Gao354ebb42012-12-07 10:10:04 +0800215 optionstr[0] = '\0';
nstraz829b40a2000-09-06 14:33:29 +0000216
Wanlong Gao354ebb42012-12-07 10:10:04 +0800217 for (i = 0; std_options[i].optstr; ++i)
218 strcat(optionstr, std_options[i].optstr);
219 if (user_optarr)
220 for (i = 0; user_optarr[i].option; ++i)
221 /* only add the option if it wasn't there already */
222 if (strchr(optionstr, user_optarr[i].option[0]) == NULL)
223 strcat(optionstr, user_optarr[i].option);
alaffincc2e5552000-07-27 17:13:18 +0000224
Wanlong Gao354ebb42012-12-07 10:10:04 +0800225 /*
226 * Loop through av parsing options.
227 */
228 while ((opt = getopt(ac, av, optionstr)) > 0) {
alaffincc2e5552000-07-27 17:13:18 +0000229
Wanlong Gao354ebb42012-12-07 10:10:04 +0800230 STD_argind = optind;
alaffincc2e5552000-07-27 17:13:18 +0000231
Wanlong Gao354ebb42012-12-07 10:10:04 +0800232 switch (opt) {
233 case '?': /* Unknown option */
nstraz94181082000-08-30 18:43:38 +0000234 return "Unknown option";
235 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800236 case ':': /* Missing Arg */
nstraz94181082000-08-30 18:43:38 +0000237 return "Missing argument";
238 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800239 case 'i': /* Iterations */
nstraz94181082000-08-30 18:43:38 +0000240 options |= OPT_iteration;
241 STD_LOOP_COUNT = atoi(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800242 if (STD_LOOP_COUNT == 0)
243 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000244 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800245 case 'P': /* Delay between iterations */
nstraz94181082000-08-30 18:43:38 +0000246 options |= OPT_delay;
247 STD_LOOP_DELAY = atof(optarg);
248 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800249 case 'I': /* Time duration */
nstraz94181082000-08-30 18:43:38 +0000250 options |= OPT_duration;
251 STD_LOOP_DURATION = atof(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800252 if (STD_LOOP_DURATION == 0.0)
253 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000254 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800255 case 'c': /* Copies */
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100256 fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800257 "WARNING * WARNING * WARNING * WARNING * "
258 "WARNING * WARNING * WARNING * WARNING\n\n"
259 "The -c option is broken by desing. See:\n\n"
260 "http://www.mail-archive.com/"
261 "ltp-list@lists.sourceforge.net/msg13418.html\n"
262 "\nIn short don't use it in runtest files "
263 "as the option will be removed.\n\n"
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100264 "WARNING * WARNING * WARNING * WARNING * "
265 "WARNING * WARNING * WARNING * WARNING\n\n");
nstraz94181082000-08-30 18:43:38 +0000266 options |= OPT_copies;
267 STD_COPIES = atoi(optarg);
268 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800269 case 'f': /* Functional testing */
nstraz94181082000-08-30 18:43:38 +0000270 STD_FUNCTIONAL_TEST = 0;
271 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800272 case 'p': /* Pause for SIGUSR1 */
nstraz94181082000-08-30 18:43:38 +0000273 STD_PAUSE = 1;
274 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800275 case 't': /* syscall timing */
nstraz94181082000-08-30 18:43:38 +0000276 STD_TIMING_ON = 1;
277 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800278 case 'e': /* errno loggin */
nstraz94181082000-08-30 18:43:38 +0000279 STD_ERRNO_LOG = 1;
280 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800281 case 'h': /* Help */
nstraz94181082000-08-30 18:43:38 +0000282 print_help(uhf);
283 exit(0);
284 break;
robbiewd34d5812005-07-11 22:28:09 +0000285#ifdef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800286 case 'C': /* Run child */
robbiewd34d5812005-07-11 22:28:09 +0000287 child_args = optarg;
288 break;
289#endif
nstraz94181082000-08-30 18:43:38 +0000290 default:
vapier45a8ba02009-07-20 10:59:32 +0000291
Wanlong Gao354ebb42012-12-07 10:10:04 +0800292 /* Check all the user specified options */
293 found = 0;
294 for (i = 0; user_optarr[i].option; ++i) {
alaffincc2e5552000-07-27 17:13:18 +0000295
Wanlong Gao354ebb42012-12-07 10:10:04 +0800296 if (opt == user_optarr[i].option[0]) {
297 /* Yup, This is a user option, set the flag and look for argument */
298 if (user_optarr[i].flag) {
299 *user_optarr[i].flag = 1;
300 }
301 found++;
alaffincc2e5552000-07-27 17:13:18 +0000302
Wanlong Gao354ebb42012-12-07 10:10:04 +0800303 /* save the argument at the user's location */
304 if (user_optarr[i].
305 option[strlen(user_optarr[i].option)
306 - 1] == ':') {
307 *user_optarr[i].arg = optarg;
308 }
309 break; /* option found - break out of the for loop */
310 }
311 }
312 /* This condition "should never happen". SO CHECK FOR IT!!!! */
313 if (!found) {
314 sprintf(Mesg2,
315 "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL "
316 "ERROR", opt);
317 return (Mesg2);
318 }
319 }
320
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200321 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800322 free(optionstr);
323
324 STD_argind = optind;
325
326 /*
327 * Turn on debug
328 */
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200329 if (getenv("USC_DEBUG") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800330 Debug = 1;
331 printf("env USC_DEBUG is defined, turning on debug\n");
332 }
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200333 if (getenv("USC_VERBOSE") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800334 Debug = 1;
335 printf("env USC_VERBOSE is defined, turning on debug\n");
alaffincc2e5552000-07-27 17:13:18 +0000336 }
337
Wanlong Gao354ebb42012-12-07 10:10:04 +0800338 /*
339 * If the USC_ITERATION_ENV environmental variable is set to
340 * a number, use that number as iteration count (same as -c option).
341 * The -c option with arg will be used even if this env var is set.
342 */
343 if (!(options & OPT_iteration)
344 && (ptr = getenv(USC_ITERATION_ENV)) != NULL) {
345 if (sscanf(ptr, "%i", &k) == 1) {
346 if (k == 0) { /* if arg is 0, set infinite loop flag */
347 STD_INFINITE = 1;
348 if (Debug)
349 printf
350 ("Using env %s, set STD_INFINITE to 1\n",
351 USC_ITERATION_ENV);
352 } else { /* else, set the loop count to the arguement */
353 STD_LOOP_COUNT = k;
354 if (Debug)
355 printf
356 ("Using env %s, set STD_LOOP_COUNT to %d\n",
357 USC_ITERATION_ENV, k);
358 }
359 }
360 }
alaffincc2e5552000-07-27 17:13:18 +0000361
Wanlong Gao354ebb42012-12-07 10:10:04 +0800362 /*
363 * If the USC_NO_FUNC_CHECK environmental variable is set, we'll
364 * unset the STD_FUNCTIONAL_TEST variable.
365 */
366 if (!(options & OPT_nofunccheck) &&
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200367 getenv(USC_NO_FUNC_CHECK) != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800368 STD_FUNCTIONAL_TEST = 0; /* Turn off functional testing */
Garrett Cooper903910d2010-11-23 09:27:44 -0800369 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800370 printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
371 USC_NO_FUNC_CHECK);
372 }
373
374 /*
375 * If the USC_LOOP_WALLTIME environmental variable is set,
376 * use that number as duration (same as -I option).
377 * The -I option with arg will be used even if this env var is set.
378 */
379
380 if (!(options & OPT_duration) &&
381 (ptr = getenv(USC_LOOP_WALLTIME)) != NULL) {
382 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
383 STD_LOOP_DURATION = ftmp;
384 if (Debug)
385 printf
386 ("Using env %s, set STD_LOOP_DURATION to %f\n",
387 USC_LOOP_WALLTIME, ftmp);
388 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
389 STD_INFINITE = 1;
390 if (Debug)
391 printf
392 ("Using env %s, set STD_INFINITE to 1\n",
393 USC_LOOP_WALLTIME);
394 }
395 }
396 }
397 if (!(options & OPT_duration) && (ptr = getenv("USC_DURATION")) != NULL) {
398 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
399 STD_LOOP_DURATION = ftmp;
400 if (Debug)
401 printf
402 ("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n",
403 ftmp);
404 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
405 STD_INFINITE = 1;
406 if (Debug)
407 printf
408 ("Using env USC_DURATION, set STD_INFINITE to 1\n");
409 }
410 }
411 }
412 /*
413 * If the USC_LOOP_DELAY environmental variable is set,
414 * use that number as delay in factional seconds (same as -P option).
415 * The -P option with arg will be used even if this env var is set.
416 */
417 if (!(options & OPT_delay) && (ptr = getenv(USC_LOOP_DELAY)) != NULL) {
418 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
419 STD_LOOP_DELAY = ftmp;
420 if (Debug)
421 printf
422 ("Using env %s, set STD_LOOP_DELAY = %f\n",
423 USC_LOOP_DELAY, ftmp);
424 }
425 }
426
427 /*
428 * If the USC_COPIES environmental variable is set,
429 * use that number as copies (same as -c option).
430 * The -c option with arg will be used even if this env var is set.
431 */
432 if (!(options & OPT_copies) && (ptr = getenv(USC_COPIES)) != NULL) {
433 if (sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0) {
434 if (Debug)
435 printf("Using env %s, set STD_COPIES = %d\n",
436 USC_COPIES, STD_COPIES);
437 }
438 }
439
440 /*
441 * The following are special system testing envs to turn on special
442 * hooks in the code.
443 */
444 if ((ptr = getenv("USC_TP_BARRIER")) != NULL) {
445 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
446 STD_TP_barrier = k;
447 else
448 STD_TP_barrier = 1;
Garrett Cooper903910d2010-11-23 09:27:44 -0800449 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800450 printf
451 ("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
452 STD_TP_barrier);
453 }
alaffincc2e5552000-07-27 17:13:18 +0000454
Wanlong Gao354ebb42012-12-07 10:10:04 +0800455 if ((ptr = getenv("USC_LP_BARRIER")) != NULL) {
456 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
457 STD_LP_barrier = k;
458 else
459 STD_LP_barrier = 1;
460 if (Debug)
461 printf
462 ("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
463 STD_LP_barrier);
464 }
alaffincc2e5552000-07-27 17:13:18 +0000465
Wanlong Gao354ebb42012-12-07 10:10:04 +0800466 if ((ptr = getenv("USC_TP_SHMEM")) != NULL) {
467 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
468 STD_TP_shmem_sz = k;
469 if (Debug)
470 printf
471 ("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
472 STD_TP_shmem_sz);
473 }
474 }
alaffincc2e5552000-07-27 17:13:18 +0000475
Wanlong Gao354ebb42012-12-07 10:10:04 +0800476 if ((ptr = getenv("USC_LP_SHMEM")) != NULL) {
477 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
478 STD_LP_shmem = k;
479 if (Debug)
480 printf
481 ("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
482 STD_LP_shmem);
483 }
484 }
alaffincc2e5552000-07-27 17:13:18 +0000485
Wanlong Gao354ebb42012-12-07 10:10:04 +0800486 if ((ptr = getenv("USC_LD_SHMEM")) != NULL) {
487 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
488 STD_LD_shmem = k;
489 if (Debug)
490 printf
491 ("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
492 STD_LD_shmem);
493 }
494 }
alaffincc2e5552000-07-27 17:13:18 +0000495
Wanlong Gao354ebb42012-12-07 10:10:04 +0800496 if ((ptr = getenv("USC_TP_SBRK")) != NULL) {
497 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
498 STD_TP_sbrk = k;
499 if (Debug)
500 printf
501 ("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
502 STD_TP_sbrk);
503 }
504 }
robbiewd34d5812005-07-11 22:28:09 +0000505#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800506 if ((ptr = getenv("USC_LP_SBRK")) != NULL) {
507 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
508 STD_LP_sbrk = k;
509 if (Debug)
510 printf
511 ("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
512 STD_LP_sbrk);
513 }
514 }
robbiewd34d5812005-07-11 22:28:09 +0000515#endif /* if !defined(UCLINUX) */
alaffincc2e5552000-07-27 17:13:18 +0000516
Wanlong Gao354ebb42012-12-07 10:10:04 +0800517 if ((ptr = getenv("USC_LP_RECFUN")) != NULL) {
518 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
519 STD_LP_recfun = k;
520 if (STD_bigstack != NULL)
521 STD_bigstack =
522 malloc(sizeof(struct usc_bigstack_t));
523 if (Debug)
524 printf
525 ("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
526 STD_LP_recfun);
527 }
528 }
alaffincc2e5552000-07-27 17:13:18 +0000529
Wanlong Gao354ebb42012-12-07 10:10:04 +0800530 if ((ptr = getenv("USC_LD_RECFUN")) != NULL) {
531 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
532 STD_LD_recfun = k;
533 if (STD_bigstack != NULL)
534 STD_bigstack =
535 malloc(sizeof(struct usc_bigstack_t));
536 if (Debug)
537 printf
538 ("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
539 STD_LD_recfun);
540 }
541 }
alaffincc2e5552000-07-27 17:13:18 +0000542#if UNIT_TEST
Wanlong Gao354ebb42012-12-07 10:10:04 +0800543 printf("The following variables after option and env parsing:\n");
544 printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
545 printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION);
546 printf("STD_LOOP_DELAY = %f\n", STD_LOOP_DELAY);
547 printf("STD_COPIES = %d\n", STD_COPIES);
548 printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT);
549 printf("STD_INFINITE = %d\n", STD_INFINITE);
550 printf("STD_TIMING_ON = %d\n", STD_TIMING_ON);
551 printf("STD_ERRNO_LOG = %d\n", STD_ERRNO_LOG);
552 printf("STD_PAUSE = %d\n", STD_PAUSE);
alaffincc2e5552000-07-27 17:13:18 +0000553#endif
554
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200555 return NULL;
alaffincc2e5552000-07-27 17:13:18 +0000556}
557
vapier45a8ba02009-07-20 10:59:32 +0000558/*
alaffincc2e5552000-07-27 17:13:18 +0000559 * routine to goto when we get the SIGUSR1 for STD_PAUSE
560 */
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200561static void STD_go(int sig)
alaffincc2e5552000-07-27 17:13:18 +0000562{
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200563 (void)sig;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800564 return;
alaffincc2e5552000-07-27 17:13:18 +0000565}
566
567/***********************************************************************
568 * This function will do desired end of global setup test
569 * hooks.
570 * Currently it will only do a pause waiting for sigusr1 if
571 * STD_PAUSE is set.
572 *
573 ***********************************************************************/
Cyril Hrubisee75ce32014-02-05 14:05:06 +0100574int usc_global_setup_hook(void)
alaffincc2e5552000-07-27 17:13:18 +0000575{
robbiewd34d5812005-07-11 22:28:09 +0000576#ifndef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800577 int cnt;
578 /* temp variable to store old signal action to be restored after pause */
579 int (*_TMP_FUNC) (void);
alaffincc2e5552000-07-27 17:13:18 +0000580
Wanlong Gao354ebb42012-12-07 10:10:04 +0800581 /*
582 * Fork STD_COPIES-1 copies.
583 */
584 for (cnt = 1; cnt < STD_COPIES; cnt++) {
585 switch (fork()) {
586 case -1:
587 fprintf(stderr, "%s: fork failed: %d - %s\n",
588 __FILE__, errno, strerror(errno));
589 break;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200590 case 0:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800591 cnt = STD_COPIES; /* to stop the forking */
592 break;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200593 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800594 break;
595 }
alaffincc2e5552000-07-27 17:13:18 +0000596 }
vapier45a8ba02009-07-20 10:59:32 +0000597
Wanlong Gao354ebb42012-12-07 10:10:04 +0800598 /*
599 * pause waiting for sigusr1.
600 */
601 if (STD_PAUSE) {
602 _TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);
603 pause();
604 signal(SIGUSR1, (void (*)())_TMP_FUNC);
605 }
alaffincc2e5552000-07-27 17:13:18 +0000606
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200607 if (STD_TP_sbrk || STD_LP_sbrk)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800608 STD_start_break = sbrk(0); /* get original sbreak size */
alaffincc2e5552000-07-27 17:13:18 +0000609
Wanlong Gao354ebb42012-12-07 10:10:04 +0800610 if (STD_TP_sbrk) {
611 sbrk(STD_TP_sbrk);
612 if (Debug)
613 printf("after sbrk(%d)\n", STD_TP_sbrk);
614 }
robbiewd34d5812005-07-11 22:28:09 +0000615#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800616 return 0;
alaffincc2e5552000-07-27 17:13:18 +0000617}
618
Wanlong Gao354ebb42012-12-07 10:10:04 +0800619#define USECS_PER_SEC 1000000 /* microseconds per second */
alaffincc2e5552000-07-27 17:13:18 +0000620
621/***********************************************************************
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100622 * Returns current time in microseconds since 1970.
alaffincc2e5552000-07-27 17:13:18 +0000623 ***********************************************************************/
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100624static uint64_t get_current_time(void)
alaffincc2e5552000-07-27 17:13:18 +0000625{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800626 struct timeval curtime;
alaffincc2e5552000-07-27 17:13:18 +0000627
Wanlong Gao354ebb42012-12-07 10:10:04 +0800628 gettimeofday(&curtime, NULL);
alaffincc2e5552000-07-27 17:13:18 +0000629
Wanlong Gao354ebb42012-12-07 10:10:04 +0800630 return (((uint64_t) curtime.tv_sec) * USECS_PER_SEC) + curtime.tv_usec;
alaffincc2e5552000-07-27 17:13:18 +0000631}
632
633/***********************************************************************
634 *
635 * This function will determine if test should continue iterating
636 * If the STD_INFINITE flag is set, return 1.
637 * If the STD_LOOP_COUNT variable is set, compare it against
638 * the counter.
639 * If the STD_LOOP_DURATION variable is set, compare current time against
640 * calculated stop_time.
641 * This function will return 1 until all desired looping methods
vapier45a8ba02009-07-20 10:59:32 +0000642 * have been met.
alaffincc2e5552000-07-27 17:13:18 +0000643 *
644 * counter integer is supplied by the user program.
645 ***********************************************************************/
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800646int usc_test_looping(int counter)
alaffincc2e5552000-07-27 17:13:18 +0000647{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800648 static int first_time = 1;
649 static uint64_t stop_time = 0;
650 static uint64_t delay;
651 uint64_t ct, end;
652 int keepgoing = 0;
alaffincc2e5552000-07-27 17:13:18 +0000653
654 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800655 * If this is the first iteration and we are looping for
656 * duration of STD_LOOP_DURATION seconds (fractional) or
657 * doing loop delays, get the clocks per second.
alaffincc2e5552000-07-27 17:13:18 +0000658 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800659 if (first_time) {
660 first_time = 0;
661
662 /*
663 * If looping for duration, calculate stop time in
664 * clocks.
665 */
666 if (STD_LOOP_DURATION) {
667 stop_time =
668 (uint64_t) (USECS_PER_SEC * STD_LOOP_DURATION)
669 + get_current_time();
670 }
671
672 /*
673 * If doing delay each iteration, calcuate the number
674 * of clocks for each delay.
675 */
676 if (STD_LOOP_DELAY)
677 delay = USECS_PER_SEC * STD_LOOP_DELAY;
alaffincc2e5552000-07-27 17:13:18 +0000678 }
679
680 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800681 * if delay each iteration, loop for delay clocks.
682 * This will not be done on first iteration.
683 * The delay will happen before determining if
684 * there will be another iteration.
alaffincc2e5552000-07-27 17:13:18 +0000685 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800686 else if (STD_LOOP_DELAY) {
687 ct = get_current_time();
688 end = ct + delay;
689 while (ct < end) {
690 /*
691 * The following are special test hooks in the delay loop.
692 */
693 if (STD_LD_recfun) {
694 if (Debug)
695 printf
696 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
697 STD_LD_recfun);
698 usc_recressive_func(0, STD_LD_recfun,
699 *STD_bigstack);
700 }
vapier45a8ba02009-07-20 10:59:32 +0000701
Wanlong Gao354ebb42012-12-07 10:10:04 +0800702 ct = get_current_time();
703 }
704 }
705
706 if (STD_INFINITE)
707 keepgoing++;
708
709 if (STD_LOOP_COUNT && counter < STD_LOOP_COUNT)
710 keepgoing++;
711
712 if (STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time)
713 keepgoing++;
714
715 if (keepgoing == 0)
716 return 0;
717
718 /*
719 * The following code allows special system testing hooks.
720 */
721
722 if (STD_LP_recfun) {
Garrett Cooper903910d2010-11-23 09:27:44 -0800723 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800724 printf
725 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
726 STD_LP_recfun);
727 usc_recressive_func(0, STD_LP_recfun, *STD_bigstack);
alaffincc2e5552000-07-27 17:13:18 +0000728 }
robbiewd34d5812005-07-11 22:28:09 +0000729#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800730 if (STD_LP_sbrk) {
731 if (Debug)
732 printf("about to do sbrk(%d)\n", STD_LP_sbrk);
733 sbrk(STD_LP_sbrk);
734 }
robbiewd34d5812005-07-11 22:28:09 +0000735#endif
alaffincc2e5552000-07-27 17:13:18 +0000736
Wanlong Gao354ebb42012-12-07 10:10:04 +0800737 if (keepgoing)
738 return 1;
739 else
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200740 return 0;
alaffincc2e5552000-07-27 17:13:18 +0000741}
742
alaffincc2e5552000-07-27 17:13:18 +0000743/*
744 * This function recressively calls itself max times.
vapier45a8ba02009-07-20 10:59:32 +0000745 */
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800746static void usc_recressive_func(int cnt, int max, struct usc_bigstack_t bstack)
alaffincc2e5552000-07-27 17:13:18 +0000747{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800748 if (cnt < max)
749 usc_recressive_func(cnt + 1, max, bstack);
alaffincc2e5552000-07-27 17:13:18 +0000750
751}
752
753#if UNIT_TEST
Cyril Hrubis15899192014-05-27 16:57:45 +0200754#include <time.h>
755
alaffincc2e5552000-07-27 17:13:18 +0000756/******************************************************************************
757 * UNIT TEST CODE
758 * UNIT TEST CODE
vapier45a8ba02009-07-20 10:59:32 +0000759 *
alaffincc2e5552000-07-27 17:13:18 +0000760 * this following code is provide so that unit testing can
761 * be done fairly easily.
762 ******************************************************************************/
763
764int Help = 0;
765int Help2 = 0;
766char *ptr;
767
768/*
769 * Code from usctest.h that not part of this file since we are the library.
770 */
771
772struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
773
Markos Chandrasfd4ada72012-01-03 11:10:37 +0000774long TEST_RETURN;
alaffincc2e5552000-07-27 17:13:18 +0000775int TEST_ERRNO;
776
alaffincc2e5552000-07-27 17:13:18 +0000777/* for test specific parse_opts options */
778option_t Options[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800779 {"help", &Help2, NULL}, /* -help option */
780 {"h", &Help, NULL}, /* -h option */
alaffincc2e5552000-07-27 17:13:18 +0000781
782#if INVALID_TEST_CASES
Wanlong Gao354ebb42012-12-07 10:10:04 +0800783 {"missingflag", NULL, &ptr}, /* error */
784 {"missingarg:", &Help, NULL}, /* error */
785#endif /* INVALID_TEST_CASES */
alaffincc2e5552000-07-27 17:13:18 +0000786
Wanlong Gao354ebb42012-12-07 10:10:04 +0800787 {NULL, NULL, NULL}
alaffincc2e5552000-07-27 17:13:18 +0000788};
789
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800790int main(int argc, char **argv)
alaffincc2e5552000-07-27 17:13:18 +0000791{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800792 int lc;
793 char *msg;
794 struct timeval t;
795 int cnt;
alaffincc2e5552000-07-27 17:13:18 +0000796
Wanlong Gao354ebb42012-12-07 10:10:04 +0800797 if ((msg = parse_opts(argc, argv, Options, NULL)) != NULL) {
798 printf("ERROR: %s\n", msg);
799 exit(1);
800 }
alaffincc2e5552000-07-27 17:13:18 +0000801
Wanlong Gao354ebb42012-12-07 10:10:04 +0800802 TEST_PAUSE;
alaffincc2e5552000-07-27 17:13:18 +0000803
Wanlong Gao354ebb42012-12-07 10:10:04 +0800804 for (lc = 0; TEST_LOOPING(lc); lc++) {
vapier45a8ba02009-07-20 10:59:32 +0000805
Wanlong Gao354ebb42012-12-07 10:10:04 +0800806 TEST(gettimeofday(&t, NULL));
807 printf("iter=%d: sec:%d, usec:%6.6d %s", lc + 1, t.tv_sec,
808 t.tv_usec, ctime(&t.tv_sec));
809 }
alaffincc2e5552000-07-27 17:13:18 +0000810
Wanlong Gao354ebb42012-12-07 10:10:04 +0800811 TEST_CLEANUP;
alaffincc2e5552000-07-27 17:13:18 +0000812
Wanlong Gao354ebb42012-12-07 10:10:04 +0800813 exit(0);
alaffincc2e5552000-07-27 17:13:18 +0000814}
815
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800816#endif /* UNIT_TEST */