blob: ffb18af0aa47d8242ac22a4a2ae736d5675a3543 [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#if UNIT_TEST
46#include <time.h>
47#endif /* UNIT_TEST */
48
49#include "test.h"
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020050#include "ltp_priv.h"
alaffincc2e5552000-07-27 17:13:18 +000051#include "usctest.h"
alaffincc2e5552000-07-27 17:13:18 +000052
53#ifndef USC_COPIES
54#define USC_COPIES "USC_COPIES"
55#endif
56
57#ifndef UNIT_TEST
58#define UNIT_TEST 0
59#endif
60
61#ifndef DEBUG
62#define DEBUG 0
63#endif
64
alaffincc2e5552000-07-27 17:13:18 +000065/* The timing information block. */
Wanlong Gao354ebb42012-12-07 10:10:04 +080066struct tblock tblock = { 0, ((long)-1) >> 1, 0, 0 };
alaffincc2e5552000-07-27 17:13:18 +000067
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080068#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +080069extern pid_t spawned_program_pid;
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080070#endif
alaffincc2e5552000-07-27 17:13:18 +000071
72/* Define flags and args for standard options */
Wanlong Gao354ebb42012-12-07 10:10:04 +080073int STD_FUNCTIONAL_TEST = 1, /* flag indicating to do functional testing code */
74 STD_TIMING_ON = 0, /* flag indicating to print timing stats */
75 STD_PAUSE = 0, /* flag indicating to pause before actual start, */
76 /* for contention mode */
77 STD_INFINITE = 0, /* flag indciating to loop forever */
78 STD_LOOP_COUNT = 1, /* number of iterations */
79 STD_COPIES = 1, /* number of copies */
80 STD_ERRNO_LOG = 0; /* flag indicating to do errno logging */
alaffincc2e5552000-07-27 17:13:18 +000081
Wanlong Gao354ebb42012-12-07 10:10:04 +080082float STD_LOOP_DURATION = 0.0, /* duration value in fractional seconds */
83 STD_LOOP_DELAY = 0.0; /* loop delay value in fractional seconds */
alaffincc2e5552000-07-27 17:13:18 +000084
85char **STD_opt_arr = NULL; /* array of option strings */
Wanlong Gao354ebb42012-12-07 10:10:04 +080086int STD_nopts = 0, /* number of elements in STD_opt_arr */
87 STD_argind = 1; /* argv index to next argv element */
alaffincc2e5552000-07-27 17:13:18 +000088 /* (first argument) */
89 /* To getopt users, it is like optind */
90
91/*
92 * The following variables are to support system testing additions.
93 */
Wanlong Gao354ebb42012-12-07 10:10:04 +080094static int STD_TP_barrier = 0; /* flag to do barrier in TEST_PAUSE */
alaffincc2e5552000-07-27 17:13:18 +000095 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +080096static int STD_LP_barrier = 0; /* flag to do barrier in TEST_LOOPING */
alaffincc2e5552000-07-27 17:13:18 +000097 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +080098static int STD_TP_shmem_sz = 0; /* shmalloc this many words per pe in TEST_PAUSE */
99static int STD_LD_shmem = 0; /* flag to do shmem_puts and shmem_gets during delay */
100static int STD_LP_shmem = 0; /* flag to do shmem_puts and gets during TEST_LOOPING */
101static int STD_LD_recfun = 0; /* do recressive function calls in loop delay */
102static int STD_LP_recfun = 0; /* do recressive function calls in TEST_LOOPING */
103static int STD_TP_sbrk = 0; /* do sbrk in TEST_PAUSE */
104static int STD_LP_sbrk = 0; /* do sbrk in TEST_LOOPING */
105static char *STD_start_break = 0; /* original sbrk size */
106static int Debug = 0;
alaffincc2e5552000-07-27 17:13:18 +0000107
nstraz94181082000-08-30 18:43:38 +0000108struct std_option_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800109 char *optstr;
110 char *help;
111 char *flag;
112 char **arg;
nstraz94181082000-08-30 18:43:38 +0000113} std_options[] = {
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200114 {"c:", " -c n Run n copies concurrently\n", NULL, NULL},
115 {"e", " -e Turn on errno logging\n", NULL, NULL},
116 {"f", " -f Turn off functional testing\n", NULL, NULL},
117 {"h", " -h Show this help screen\n", NULL, NULL},
118 {"i:", " -i n Execute test n times\n", NULL, NULL},
119 {"I:", " -I x Execute test for x seconds\n", NULL, NULL},
120 {"p", " -p Pause for SIGUSR1 before starting\n", NULL, NULL},
121 {"P:", " -P x Pause for x seconds between iterations\n", NULL, NULL},
122 {"t", " -t Turn on syscall timing\n", NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000123#ifdef UCLINUX
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200124 {"C:",
125 " -C ARG Run the child process with arguments ARG (for internal use)\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800126 NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000127#endif
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200128 {NULL, NULL, NULL, NULL}};
nstraz94181082000-08-30 18:43:38 +0000129
alaffincc2e5552000-07-27 17:13:18 +0000130/*
131 * Structure for usc_recressive_func argument
132 */
133struct usc_bigstack_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134 char space[4096];
alaffincc2e5552000-07-27 17:13:18 +0000135};
136
Wanlong Gao354ebb42012-12-07 10:10:04 +0800137static struct usc_bigstack_t *STD_bigstack = NULL;
alaffincc2e5552000-07-27 17:13:18 +0000138
alaffincc2e5552000-07-27 17:13:18 +0000139/*
140 * Counter of errnos returned (-e option). Indexed by errno.
141 * Make the array USC_MAX_ERRNO long. That is the first Fortran
142 * Lib errno. No syscall should return an errno that high.
143 */
144int STD_ERRNO_LIST[USC_MAX_ERRNO];
145
146/* define the string length for Mesg and Mesg2 strings */
147#define STRLEN 2048
148
alaffincc2e5552000-07-27 17:13:18 +0000149static char Mesg2[STRLEN]; /* holds possible return string */
150static void usc_recressive_func();
151
152/*
153 * Define bits for options that might have env variable default
154 */
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200155#define OPT_iteration 01
156#define OPT_nofunccheck 02
157#define OPT_duration 04
158#define OPT_delay 010
159#define OPT_copies 020
alaffincc2e5552000-07-27 17:13:18 +0000160
robbiewd34d5812005-07-11 22:28:09 +0000161#ifdef UCLINUX
162/* Allocated and used in self_exec.c: */
163extern char *child_args; /* Arguments to child when -C is used */
164#endif
alaffincc2e5552000-07-27 17:13:18 +0000165
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200166static void print_help(void (*user_help)(void))
167{
168 int i;
169
170 for (i = 0; std_options[i].optstr; ++i) {
171 if (std_options[i].help)
172 printf("%s", std_options[i].help);
173 }
174
175 if (user_help)
176 user_help();
177}
178
alaffincc2e5552000-07-27 17:13:18 +0000179/**********************************************************************
vapier45a8ba02009-07-20 10:59:32 +0000180 * parse_opts:
alaffincc2e5552000-07-27 17:13:18 +0000181 **********************************************************************/
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200182const char *parse_opts(int ac, char **av, const option_t * user_optarr,
183 void (*uhf)(void))
alaffincc2e5552000-07-27 17:13:18 +0000184{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800185 int found; /* flag to indicate that an option specified was */
186 /* found in the user's list */
187 int k; /* scratch integer for returns and short time usage */
188 float ftmp; /* tmp float for parsing env variables */
189 char *ptr; /* used in getting env variables */
190 int options = 0; /* no options specified */
191 int optstrlen, i;
192 char *optionstr;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200193 int opt;
alaffincc2e5552000-07-27 17:13:18 +0000194
Wanlong Gao354ebb42012-12-07 10:10:04 +0800195 /*
196 * If not the first time this function is called, release the old STD_opt_arr
197 * vector.
198 */
alaffincc2e5552000-07-27 17:13:18 +0000199
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800200#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +0800201 spawned_program_pid = getpid();
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800202#endif
203
Wanlong Gao354ebb42012-12-07 10:10:04 +0800204 if (STD_opt_arr != NULL) {
205 free(STD_opt_arr);
206 STD_opt_arr = NULL;
nstraz94181082000-08-30 18:43:38 +0000207 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800208 /* Calculate how much space we need for the option string */
209 optstrlen = 0;
210 for (i = 0; std_options[i].optstr; ++i)
211 optstrlen += strlen(std_options[i].optstr);
212 if (user_optarr)
213 for (i = 0; user_optarr[i].option; ++i) {
214 if (strlen(user_optarr[i].option) > 2)
215 return
216 "parse_opts: ERROR - Only short options are allowed";
217 optstrlen += strlen(user_optarr[i].option);
218 }
219 optstrlen += 1;
alaffincc2e5552000-07-27 17:13:18 +0000220
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 /* Create the option string for getopt */
222 optionstr = malloc(optstrlen);
223 if (!optionstr)
224 return
225 "parse_opts: ERROR - Could not allocate memory for optionstr";
alaffincc2e5552000-07-27 17:13:18 +0000226
Wanlong Gao354ebb42012-12-07 10:10:04 +0800227 optionstr[0] = '\0';
nstraz829b40a2000-09-06 14:33:29 +0000228
Wanlong Gao354ebb42012-12-07 10:10:04 +0800229 for (i = 0; std_options[i].optstr; ++i)
230 strcat(optionstr, std_options[i].optstr);
231 if (user_optarr)
232 for (i = 0; user_optarr[i].option; ++i)
233 /* only add the option if it wasn't there already */
234 if (strchr(optionstr, user_optarr[i].option[0]) == NULL)
235 strcat(optionstr, user_optarr[i].option);
alaffincc2e5552000-07-27 17:13:18 +0000236
237#if DEBUG > 1
Wanlong Gao354ebb42012-12-07 10:10:04 +0800238 printf("STD_nopts = %d\n", STD_nopts);
alaffincc2e5552000-07-27 17:13:18 +0000239#endif
240
Wanlong Gao354ebb42012-12-07 10:10:04 +0800241 /*
242 * Loop through av parsing options.
243 */
244 while ((opt = getopt(ac, av, optionstr)) > 0) {
alaffincc2e5552000-07-27 17:13:18 +0000245
Wanlong Gao354ebb42012-12-07 10:10:04 +0800246 STD_argind = optind;
alaffincc2e5552000-07-27 17:13:18 +0000247#if DEBUG > 0
Wanlong Gao354ebb42012-12-07 10:10:04 +0800248 printf("parse_opts: getopt returned '%c'\n", opt);
alaffincc2e5552000-07-27 17:13:18 +0000249#endif
alaffincc2e5552000-07-27 17:13:18 +0000250
Wanlong Gao354ebb42012-12-07 10:10:04 +0800251 switch (opt) {
252 case '?': /* Unknown option */
nstraz94181082000-08-30 18:43:38 +0000253 return "Unknown option";
254 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800255 case ':': /* Missing Arg */
nstraz94181082000-08-30 18:43:38 +0000256 return "Missing argument";
257 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 case 'i': /* Iterations */
nstraz94181082000-08-30 18:43:38 +0000259 options |= OPT_iteration;
260 STD_LOOP_COUNT = atoi(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800261 if (STD_LOOP_COUNT == 0)
262 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000263 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800264 case 'P': /* Delay between iterations */
nstraz94181082000-08-30 18:43:38 +0000265 options |= OPT_delay;
266 STD_LOOP_DELAY = atof(optarg);
267 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800268 case 'I': /* Time duration */
nstraz94181082000-08-30 18:43:38 +0000269 options |= OPT_duration;
270 STD_LOOP_DURATION = atof(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800271 if (STD_LOOP_DURATION == 0.0)
272 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000273 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800274 case 'c': /* Copies */
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100275 fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800276 "WARNING * WARNING * WARNING * WARNING * "
277 "WARNING * WARNING * WARNING * WARNING\n\n"
278 "The -c option is broken by desing. See:\n\n"
279 "http://www.mail-archive.com/"
280 "ltp-list@lists.sourceforge.net/msg13418.html\n"
281 "\nIn short don't use it in runtest files "
282 "as the option will be removed.\n\n"
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100283 "WARNING * WARNING * WARNING * WARNING * "
284 "WARNING * WARNING * WARNING * WARNING\n\n");
nstraz94181082000-08-30 18:43:38 +0000285 options |= OPT_copies;
286 STD_COPIES = atoi(optarg);
287 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800288 case 'f': /* Functional testing */
nstraz94181082000-08-30 18:43:38 +0000289 STD_FUNCTIONAL_TEST = 0;
290 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800291 case 'p': /* Pause for SIGUSR1 */
nstraz94181082000-08-30 18:43:38 +0000292 STD_PAUSE = 1;
293 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800294 case 't': /* syscall timing */
nstraz94181082000-08-30 18:43:38 +0000295 STD_TIMING_ON = 1;
296 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800297 case 'e': /* errno loggin */
nstraz94181082000-08-30 18:43:38 +0000298 STD_ERRNO_LOG = 1;
299 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800300 case 'h': /* Help */
nstraz94181082000-08-30 18:43:38 +0000301 print_help(uhf);
302 exit(0);
303 break;
robbiewd34d5812005-07-11 22:28:09 +0000304#ifdef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800305 case 'C': /* Run child */
robbiewd34d5812005-07-11 22:28:09 +0000306 child_args = optarg;
307 break;
308#endif
nstraz94181082000-08-30 18:43:38 +0000309 default:
vapier45a8ba02009-07-20 10:59:32 +0000310
Wanlong Gao354ebb42012-12-07 10:10:04 +0800311 /* Check all the user specified options */
312 found = 0;
313 for (i = 0; user_optarr[i].option; ++i) {
alaffincc2e5552000-07-27 17:13:18 +0000314
Wanlong Gao354ebb42012-12-07 10:10:04 +0800315 if (opt == user_optarr[i].option[0]) {
316 /* Yup, This is a user option, set the flag and look for argument */
317 if (user_optarr[i].flag) {
318 *user_optarr[i].flag = 1;
319 }
320 found++;
alaffincc2e5552000-07-27 17:13:18 +0000321
Wanlong Gao354ebb42012-12-07 10:10:04 +0800322 /* save the argument at the user's location */
323 if (user_optarr[i].
324 option[strlen(user_optarr[i].option)
325 - 1] == ':') {
326 *user_optarr[i].arg = optarg;
327 }
328 break; /* option found - break out of the for loop */
329 }
330 }
331 /* This condition "should never happen". SO CHECK FOR IT!!!! */
332 if (!found) {
333 sprintf(Mesg2,
334 "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL "
335 "ERROR", opt);
336 return (Mesg2);
337 }
338 }
339
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200340 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800341 free(optionstr);
342
343 STD_argind = optind;
344
345 /*
346 * Turn on debug
347 */
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200348 if (getenv("USC_DEBUG") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800349 Debug = 1;
350 printf("env USC_DEBUG is defined, turning on debug\n");
351 }
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200352 if (getenv("USC_VERBOSE") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800353 Debug = 1;
354 printf("env USC_VERBOSE is defined, turning on debug\n");
alaffincc2e5552000-07-27 17:13:18 +0000355 }
356
Wanlong Gao354ebb42012-12-07 10:10:04 +0800357 /*
358 * If the USC_ITERATION_ENV environmental variable is set to
359 * a number, use that number as iteration count (same as -c option).
360 * The -c option with arg will be used even if this env var is set.
361 */
362 if (!(options & OPT_iteration)
363 && (ptr = getenv(USC_ITERATION_ENV)) != NULL) {
364 if (sscanf(ptr, "%i", &k) == 1) {
365 if (k == 0) { /* if arg is 0, set infinite loop flag */
366 STD_INFINITE = 1;
367 if (Debug)
368 printf
369 ("Using env %s, set STD_INFINITE to 1\n",
370 USC_ITERATION_ENV);
371 } else { /* else, set the loop count to the arguement */
372 STD_LOOP_COUNT = k;
373 if (Debug)
374 printf
375 ("Using env %s, set STD_LOOP_COUNT to %d\n",
376 USC_ITERATION_ENV, k);
377 }
378 }
379 }
alaffincc2e5552000-07-27 17:13:18 +0000380
Wanlong Gao354ebb42012-12-07 10:10:04 +0800381 /*
382 * If the USC_NO_FUNC_CHECK environmental variable is set, we'll
383 * unset the STD_FUNCTIONAL_TEST variable.
384 */
385 if (!(options & OPT_nofunccheck) &&
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200386 getenv(USC_NO_FUNC_CHECK) != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800387 STD_FUNCTIONAL_TEST = 0; /* Turn off functional testing */
Garrett Cooper903910d2010-11-23 09:27:44 -0800388 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800389 printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
390 USC_NO_FUNC_CHECK);
391 }
392
393 /*
394 * If the USC_LOOP_WALLTIME environmental variable is set,
395 * use that number as duration (same as -I option).
396 * The -I option with arg will be used even if this env var is set.
397 */
398
399 if (!(options & OPT_duration) &&
400 (ptr = getenv(USC_LOOP_WALLTIME)) != NULL) {
401 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
402 STD_LOOP_DURATION = ftmp;
403 if (Debug)
404 printf
405 ("Using env %s, set STD_LOOP_DURATION to %f\n",
406 USC_LOOP_WALLTIME, ftmp);
407 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
408 STD_INFINITE = 1;
409 if (Debug)
410 printf
411 ("Using env %s, set STD_INFINITE to 1\n",
412 USC_LOOP_WALLTIME);
413 }
414 }
415 }
416 if (!(options & OPT_duration) && (ptr = getenv("USC_DURATION")) != NULL) {
417 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
418 STD_LOOP_DURATION = ftmp;
419 if (Debug)
420 printf
421 ("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n",
422 ftmp);
423 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
424 STD_INFINITE = 1;
425 if (Debug)
426 printf
427 ("Using env USC_DURATION, set STD_INFINITE to 1\n");
428 }
429 }
430 }
431 /*
432 * If the USC_LOOP_DELAY environmental variable is set,
433 * use that number as delay in factional seconds (same as -P option).
434 * The -P option with arg will be used even if this env var is set.
435 */
436 if (!(options & OPT_delay) && (ptr = getenv(USC_LOOP_DELAY)) != NULL) {
437 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
438 STD_LOOP_DELAY = ftmp;
439 if (Debug)
440 printf
441 ("Using env %s, set STD_LOOP_DELAY = %f\n",
442 USC_LOOP_DELAY, ftmp);
443 }
444 }
445
446 /*
447 * If the USC_COPIES environmental variable is set,
448 * use that number as copies (same as -c option).
449 * The -c option with arg will be used even if this env var is set.
450 */
451 if (!(options & OPT_copies) && (ptr = getenv(USC_COPIES)) != NULL) {
452 if (sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0) {
453 if (Debug)
454 printf("Using env %s, set STD_COPIES = %d\n",
455 USC_COPIES, STD_COPIES);
456 }
457 }
458
459 /*
460 * The following are special system testing envs to turn on special
461 * hooks in the code.
462 */
463 if ((ptr = getenv("USC_TP_BARRIER")) != NULL) {
464 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
465 STD_TP_barrier = k;
466 else
467 STD_TP_barrier = 1;
Garrett Cooper903910d2010-11-23 09:27:44 -0800468 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800469 printf
470 ("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
471 STD_TP_barrier);
472 }
alaffincc2e5552000-07-27 17:13:18 +0000473
Wanlong Gao354ebb42012-12-07 10:10:04 +0800474 if ((ptr = getenv("USC_LP_BARRIER")) != NULL) {
475 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
476 STD_LP_barrier = k;
477 else
478 STD_LP_barrier = 1;
479 if (Debug)
480 printf
481 ("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
482 STD_LP_barrier);
483 }
alaffincc2e5552000-07-27 17:13:18 +0000484
Wanlong Gao354ebb42012-12-07 10:10:04 +0800485 if ((ptr = getenv("USC_TP_SHMEM")) != NULL) {
486 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
487 STD_TP_shmem_sz = k;
488 if (Debug)
489 printf
490 ("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
491 STD_TP_shmem_sz);
492 }
493 }
alaffincc2e5552000-07-27 17:13:18 +0000494
Wanlong Gao354ebb42012-12-07 10:10:04 +0800495 if ((ptr = getenv("USC_LP_SHMEM")) != NULL) {
496 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
497 STD_LP_shmem = k;
498 if (Debug)
499 printf
500 ("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
501 STD_LP_shmem);
502 }
503 }
alaffincc2e5552000-07-27 17:13:18 +0000504
Wanlong Gao354ebb42012-12-07 10:10:04 +0800505 if ((ptr = getenv("USC_LD_SHMEM")) != NULL) {
506 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
507 STD_LD_shmem = k;
508 if (Debug)
509 printf
510 ("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
511 STD_LD_shmem);
512 }
513 }
alaffincc2e5552000-07-27 17:13:18 +0000514
Wanlong Gao354ebb42012-12-07 10:10:04 +0800515 if ((ptr = getenv("USC_TP_SBRK")) != NULL) {
516 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
517 STD_TP_sbrk = k;
518 if (Debug)
519 printf
520 ("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
521 STD_TP_sbrk);
522 }
523 }
robbiewd34d5812005-07-11 22:28:09 +0000524#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800525 if ((ptr = getenv("USC_LP_SBRK")) != NULL) {
526 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
527 STD_LP_sbrk = k;
528 if (Debug)
529 printf
530 ("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
531 STD_LP_sbrk);
532 }
533 }
robbiewd34d5812005-07-11 22:28:09 +0000534#endif /* if !defined(UCLINUX) */
alaffincc2e5552000-07-27 17:13:18 +0000535
Wanlong Gao354ebb42012-12-07 10:10:04 +0800536 if ((ptr = getenv("USC_LP_RECFUN")) != NULL) {
537 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
538 STD_LP_recfun = k;
539 if (STD_bigstack != NULL)
540 STD_bigstack =
541 malloc(sizeof(struct usc_bigstack_t));
542 if (Debug)
543 printf
544 ("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
545 STD_LP_recfun);
546 }
547 }
alaffincc2e5552000-07-27 17:13:18 +0000548
Wanlong Gao354ebb42012-12-07 10:10:04 +0800549 if ((ptr = getenv("USC_LD_RECFUN")) != NULL) {
550 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
551 STD_LD_recfun = k;
552 if (STD_bigstack != NULL)
553 STD_bigstack =
554 malloc(sizeof(struct usc_bigstack_t));
555 if (Debug)
556 printf
557 ("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
558 STD_LD_recfun);
559 }
560 }
alaffincc2e5552000-07-27 17:13:18 +0000561#if UNIT_TEST
Wanlong Gao354ebb42012-12-07 10:10:04 +0800562 printf("The following variables after option and env parsing:\n");
563 printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
564 printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION);
565 printf("STD_LOOP_DELAY = %f\n", STD_LOOP_DELAY);
566 printf("STD_COPIES = %d\n", STD_COPIES);
567 printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT);
568 printf("STD_INFINITE = %d\n", STD_INFINITE);
569 printf("STD_TIMING_ON = %d\n", STD_TIMING_ON);
570 printf("STD_ERRNO_LOG = %d\n", STD_ERRNO_LOG);
571 printf("STD_PAUSE = %d\n", STD_PAUSE);
alaffincc2e5552000-07-27 17:13:18 +0000572#endif
573
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200574 return NULL;
alaffincc2e5552000-07-27 17:13:18 +0000575}
576
vapier45a8ba02009-07-20 10:59:32 +0000577/*
alaffincc2e5552000-07-27 17:13:18 +0000578 * routine to goto when we get the SIGUSR1 for STD_PAUSE
579 */
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200580static void STD_go(int sig)
alaffincc2e5552000-07-27 17:13:18 +0000581{
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200582 (void)sig;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800583 return;
alaffincc2e5552000-07-27 17:13:18 +0000584}
585
586/***********************************************************************
587 * This function will do desired end of global setup test
588 * hooks.
589 * Currently it will only do a pause waiting for sigusr1 if
590 * STD_PAUSE is set.
591 *
592 ***********************************************************************/
Cyril Hrubisee75ce32014-02-05 14:05:06 +0100593int usc_global_setup_hook(void)
alaffincc2e5552000-07-27 17:13:18 +0000594{
robbiewd34d5812005-07-11 22:28:09 +0000595#ifndef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800596 int cnt;
597 /* temp variable to store old signal action to be restored after pause */
598 int (*_TMP_FUNC) (void);
alaffincc2e5552000-07-27 17:13:18 +0000599
Wanlong Gao354ebb42012-12-07 10:10:04 +0800600 /*
601 * Fork STD_COPIES-1 copies.
602 */
603 for (cnt = 1; cnt < STD_COPIES; cnt++) {
604 switch (fork()) {
605 case -1:
606 fprintf(stderr, "%s: fork failed: %d - %s\n",
607 __FILE__, errno, strerror(errno));
608 break;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200609 case 0:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800610 cnt = STD_COPIES; /* to stop the forking */
611 break;
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200612 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800613 break;
614 }
alaffincc2e5552000-07-27 17:13:18 +0000615 }
vapier45a8ba02009-07-20 10:59:32 +0000616
Wanlong Gao354ebb42012-12-07 10:10:04 +0800617 /*
618 * pause waiting for sigusr1.
619 */
620 if (STD_PAUSE) {
621 _TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);
622 pause();
623 signal(SIGUSR1, (void (*)())_TMP_FUNC);
624 }
alaffincc2e5552000-07-27 17:13:18 +0000625
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200626 if (STD_TP_sbrk || STD_LP_sbrk)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800627 STD_start_break = sbrk(0); /* get original sbreak size */
alaffincc2e5552000-07-27 17:13:18 +0000628
Wanlong Gao354ebb42012-12-07 10:10:04 +0800629 if (STD_TP_sbrk) {
630 sbrk(STD_TP_sbrk);
631 if (Debug)
632 printf("after sbrk(%d)\n", STD_TP_sbrk);
633 }
robbiewd34d5812005-07-11 22:28:09 +0000634#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800635 return 0;
alaffincc2e5552000-07-27 17:13:18 +0000636}
637
Wanlong Gao354ebb42012-12-07 10:10:04 +0800638#define USECS_PER_SEC 1000000 /* microseconds per second */
alaffincc2e5552000-07-27 17:13:18 +0000639
640/***********************************************************************
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100641 * Returns current time in microseconds since 1970.
alaffincc2e5552000-07-27 17:13:18 +0000642 ***********************************************************************/
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100643static uint64_t get_current_time(void)
alaffincc2e5552000-07-27 17:13:18 +0000644{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800645 struct timeval curtime;
alaffincc2e5552000-07-27 17:13:18 +0000646
Wanlong Gao354ebb42012-12-07 10:10:04 +0800647 gettimeofday(&curtime, NULL);
alaffincc2e5552000-07-27 17:13:18 +0000648
Wanlong Gao354ebb42012-12-07 10:10:04 +0800649 return (((uint64_t) curtime.tv_sec) * USECS_PER_SEC) + curtime.tv_usec;
alaffincc2e5552000-07-27 17:13:18 +0000650}
651
652/***********************************************************************
653 *
654 * This function will determine if test should continue iterating
655 * If the STD_INFINITE flag is set, return 1.
656 * If the STD_LOOP_COUNT variable is set, compare it against
657 * the counter.
658 * If the STD_LOOP_DURATION variable is set, compare current time against
659 * calculated stop_time.
660 * This function will return 1 until all desired looping methods
vapier45a8ba02009-07-20 10:59:32 +0000661 * have been met.
alaffincc2e5552000-07-27 17:13:18 +0000662 *
663 * counter integer is supplied by the user program.
664 ***********************************************************************/
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800665int usc_test_looping(int counter)
alaffincc2e5552000-07-27 17:13:18 +0000666{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800667 static int first_time = 1;
668 static uint64_t stop_time = 0;
669 static uint64_t delay;
670 uint64_t ct, end;
671 int keepgoing = 0;
alaffincc2e5552000-07-27 17:13:18 +0000672
673 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800674 * If this is the first iteration and we are looping for
675 * duration of STD_LOOP_DURATION seconds (fractional) or
676 * doing loop delays, get the clocks per second.
alaffincc2e5552000-07-27 17:13:18 +0000677 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800678 if (first_time) {
679 first_time = 0;
680
681 /*
682 * If looping for duration, calculate stop time in
683 * clocks.
684 */
685 if (STD_LOOP_DURATION) {
686 stop_time =
687 (uint64_t) (USECS_PER_SEC * STD_LOOP_DURATION)
688 + get_current_time();
689 }
690
691 /*
692 * If doing delay each iteration, calcuate the number
693 * of clocks for each delay.
694 */
695 if (STD_LOOP_DELAY)
696 delay = USECS_PER_SEC * STD_LOOP_DELAY;
alaffincc2e5552000-07-27 17:13:18 +0000697 }
698
699 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800700 * if delay each iteration, loop for delay clocks.
701 * This will not be done on first iteration.
702 * The delay will happen before determining if
703 * there will be another iteration.
alaffincc2e5552000-07-27 17:13:18 +0000704 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800705 else if (STD_LOOP_DELAY) {
706 ct = get_current_time();
707 end = ct + delay;
708 while (ct < end) {
709 /*
710 * The following are special test hooks in the delay loop.
711 */
712 if (STD_LD_recfun) {
713 if (Debug)
714 printf
715 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
716 STD_LD_recfun);
717 usc_recressive_func(0, STD_LD_recfun,
718 *STD_bigstack);
719 }
vapier45a8ba02009-07-20 10:59:32 +0000720
Wanlong Gao354ebb42012-12-07 10:10:04 +0800721 ct = get_current_time();
722 }
723 }
724
725 if (STD_INFINITE)
726 keepgoing++;
727
728 if (STD_LOOP_COUNT && counter < STD_LOOP_COUNT)
729 keepgoing++;
730
731 if (STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time)
732 keepgoing++;
733
734 if (keepgoing == 0)
735 return 0;
736
737 /*
738 * The following code allows special system testing hooks.
739 */
740
741 if (STD_LP_recfun) {
Garrett Cooper903910d2010-11-23 09:27:44 -0800742 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800743 printf
744 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
745 STD_LP_recfun);
746 usc_recressive_func(0, STD_LP_recfun, *STD_bigstack);
alaffincc2e5552000-07-27 17:13:18 +0000747 }
robbiewd34d5812005-07-11 22:28:09 +0000748#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800749 if (STD_LP_sbrk) {
750 if (Debug)
751 printf("about to do sbrk(%d)\n", STD_LP_sbrk);
752 sbrk(STD_LP_sbrk);
753 }
robbiewd34d5812005-07-11 22:28:09 +0000754#endif
alaffincc2e5552000-07-27 17:13:18 +0000755
Wanlong Gao354ebb42012-12-07 10:10:04 +0800756 if (keepgoing)
757 return 1;
758 else
Cyril Hrubis2a81c752014-05-27 14:54:09 +0200759 return 0;
alaffincc2e5552000-07-27 17:13:18 +0000760}
761
alaffincc2e5552000-07-27 17:13:18 +0000762/*
763 * This function recressively calls itself max times.
vapier45a8ba02009-07-20 10:59:32 +0000764 */
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800765static void usc_recressive_func(int cnt, int max, struct usc_bigstack_t bstack)
alaffincc2e5552000-07-27 17:13:18 +0000766{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800767 if (cnt < max)
768 usc_recressive_func(cnt + 1, max, bstack);
alaffincc2e5552000-07-27 17:13:18 +0000769
770}
771
772#if UNIT_TEST
773/******************************************************************************
774 * UNIT TEST CODE
775 * UNIT TEST CODE
vapier45a8ba02009-07-20 10:59:32 +0000776 *
alaffincc2e5552000-07-27 17:13:18 +0000777 * this following code is provide so that unit testing can
778 * be done fairly easily.
779 ******************************************************************************/
780
781int Help = 0;
782int Help2 = 0;
783char *ptr;
784
785/*
786 * Code from usctest.h that not part of this file since we are the library.
787 */
788
789struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
790
Markos Chandrasfd4ada72012-01-03 11:10:37 +0000791long TEST_RETURN;
alaffincc2e5552000-07-27 17:13:18 +0000792int TEST_ERRNO;
793
alaffincc2e5552000-07-27 17:13:18 +0000794/* for test specific parse_opts options */
795option_t Options[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800796 {"help", &Help2, NULL}, /* -help option */
797 {"h", &Help, NULL}, /* -h option */
alaffincc2e5552000-07-27 17:13:18 +0000798
799#if INVALID_TEST_CASES
Wanlong Gao354ebb42012-12-07 10:10:04 +0800800 {"missingflag", NULL, &ptr}, /* error */
801 {"missingarg:", &Help, NULL}, /* error */
802#endif /* INVALID_TEST_CASES */
alaffincc2e5552000-07-27 17:13:18 +0000803
Wanlong Gao354ebb42012-12-07 10:10:04 +0800804 {NULL, NULL, NULL}
alaffincc2e5552000-07-27 17:13:18 +0000805};
806
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800807int main(int argc, char **argv)
alaffincc2e5552000-07-27 17:13:18 +0000808{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800809 int lc;
810 char *msg;
811 struct timeval t;
812 int cnt;
alaffincc2e5552000-07-27 17:13:18 +0000813
Wanlong Gao354ebb42012-12-07 10:10:04 +0800814 if ((msg = parse_opts(argc, argv, Options, NULL)) != NULL) {
815 printf("ERROR: %s\n", msg);
816 exit(1);
817 }
alaffincc2e5552000-07-27 17:13:18 +0000818
Wanlong Gao354ebb42012-12-07 10:10:04 +0800819 TEST_PAUSE;
alaffincc2e5552000-07-27 17:13:18 +0000820
Wanlong Gao354ebb42012-12-07 10:10:04 +0800821 for (lc = 0; TEST_LOOPING(lc); lc++) {
vapier45a8ba02009-07-20 10:59:32 +0000822
Wanlong Gao354ebb42012-12-07 10:10:04 +0800823 TEST(gettimeofday(&t, NULL));
824 printf("iter=%d: sec:%d, usec:%6.6d %s", lc + 1, t.tv_sec,
825 t.tv_usec, ctime(&t.tv_sec));
826 }
alaffincc2e5552000-07-27 17:13:18 +0000827
Wanlong Gao354ebb42012-12-07 10:10:04 +0800828 TEST_CLEANUP;
alaffincc2e5552000-07-27 17:13:18 +0000829
Wanlong Gao354ebb42012-12-07 10:10:04 +0800830 exit(0);
alaffincc2e5552000-07-27 17:13:18 +0000831}
832
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800833#endif /* UNIT_TEST */