blob: cd1f9c728288860cb1f0761f2ff8b9ee33a0f093 [file] [log] [blame]
alaffincc2e5552000-07-27 17:13:18 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
vapier45a8ba02009-07-20 10:59:32 +00003 *
alaffincc2e5552000-07-27 17:13:18 +00004 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
vapier45a8ba02009-07-20 10:59:32 +00007 *
alaffincc2e5552000-07-27 17:13:18 +00008 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
vapier45a8ba02009-07-20 10:59:32 +000011 *
alaffincc2e5552000-07-27 17:13:18 +000012 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
vapier45a8ba02009-07-20 10:59:32 +000018 *
alaffincc2e5552000-07-27 17:13:18 +000019 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
vapier45a8ba02009-07-20 10:59:32 +000022 *
alaffincc2e5552000-07-27 17:13:18 +000023 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
vapier45a8ba02009-07-20 10:59:32 +000025 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
alaffincc2e5552000-07-27 17:13:18 +000030 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 */
32
vapier3dc04702009-08-28 09:59:52 +000033/* $Id: parse_opts.c,v 1.14 2009/08/28 09:59:52 vapier Exp $ */
alaffincc2e5552000-07-27 17:13:18 +000034
35/**********************************************************
vapier45a8ba02009-07-20 10:59:32 +000036 *
alaffincc2e5552000-07-27 17:13:18 +000037 * OS Testing - Silicon Graphics, Inc.
vapier45a8ba02009-07-20 10:59:32 +000038 *
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020039 * FUNCTION NAME : parse_opts
vapier45a8ba02009-07-20 10:59:32 +000040 *
alaffincc2e5552000-07-27 17:13:18 +000041 * FUNCTION TITLE : parse standard & user options for system call tests
vapier45a8ba02009-07-20 10:59:32 +000042 *
alaffincc2e5552000-07-27 17:13:18 +000043 * SYNOPSIS:
44 * #include "usctest.h"
45 *
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020046 * char *parse_opts(ac, av, user_optarr, uhf)
alaffincc2e5552000-07-27 17:13:18 +000047 * int ac;
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020048 * char **av;
alaffincc2e5552000-07-27 17:13:18 +000049 * option_t user_optarr[];
nstraz94181082000-08-30 18:43:38 +000050 * void (*uhf)();
vapier45a8ba02009-07-20 10:59:32 +000051 *
alaffincc2e5552000-07-27 17:13:18 +000052 * AUTHOR : William Roske/Richard Logan
vapier45a8ba02009-07-20 10:59:32 +000053 *
alaffincc2e5552000-07-27 17:13:18 +000054 * INITIAL RELEASE : UNICOS 7.0
vapier45a8ba02009-07-20 10:59:32 +000055 *
alaffincc2e5552000-07-27 17:13:18 +000056 * DESCRIPTION
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020057 * The parse_opts library routine takes that argc and argv parameters
alaffincc2e5552000-07-27 17:13:18 +000058 * recevied by main() and an array of structures defining user options.
59 * It parses the command line setting flag and argument locations
nstraz94181082000-08-30 18:43:38 +000060 * associated with the options. It uses getopt to do the actual cmd line
61 * parsing. uhf() is a function to print user define help
alaffincc2e5552000-07-27 17:13:18 +000062 *
63 * This module contains the functions usc_global_setup_hook and
64 * usc_test_looping, which are called by marcos defined in usctest.h.
vapier45a8ba02009-07-20 10:59:32 +000065 *
alaffincc2e5552000-07-27 17:13:18 +000066 * RETURN VALUE
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020067 * parse_opts returns a pointer to an error message if an error occurs.
alaffincc2e5552000-07-27 17:13:18 +000068 * This pointer is (char *)NULL if parsing is successful.
vapier45a8ba02009-07-20 10:59:32 +000069 *
alaffincc2e5552000-07-27 17:13:18 +000070 *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
Mike Frysinger28606c12010-08-17 17:22:45 -040071#include "config.h"
alaffincc2e5552000-07-27 17:13:18 +000072#include <errno.h>
73#include <stdlib.h>
74#include <string.h>
75#include <sys/param.h>
76#include <sys/signal.h>
77#include <sys/types.h>
78#include <unistd.h>
79#include <sys/time.h>
Cyril Hrubis4d964f62012-03-07 18:02:37 +010080#include <stdint.h>
alaffincc2e5552000-07-27 17:13:18 +000081
alaffincc2e5552000-07-27 17:13:18 +000082#if UNIT_TEST
83#include <time.h>
84#endif /* UNIT_TEST */
85
86#include "test.h"
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020087#include "ltp_priv.h"
Wanlong Gao354ebb42012-12-07 10:10:04 +080088#define _USC_LIB_ 1 /* indicates we are the library to the usctest.h include */
alaffincc2e5552000-07-27 17:13:18 +000089#include "usctest.h"
alaffincc2e5552000-07-27 17:13:18 +000090
91#ifndef USC_COPIES
92#define USC_COPIES "USC_COPIES"
93#endif
94
95#ifndef UNIT_TEST
96#define UNIT_TEST 0
97#endif
98
99#ifndef DEBUG
100#define DEBUG 0
101#endif
102
alaffincc2e5552000-07-27 17:13:18 +0000103/* The timing information block. */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104struct tblock tblock = { 0, ((long)-1) >> 1, 0, 0 };
alaffincc2e5552000-07-27 17:13:18 +0000105
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800106#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107extern pid_t spawned_program_pid;
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800108#endif
alaffincc2e5552000-07-27 17:13:18 +0000109
110/* Define flags and args for standard options */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800111int STD_FUNCTIONAL_TEST = 1, /* flag indicating to do functional testing code */
112 STD_TIMING_ON = 0, /* flag indicating to print timing stats */
113 STD_PAUSE = 0, /* flag indicating to pause before actual start, */
114 /* for contention mode */
115 STD_INFINITE = 0, /* flag indciating to loop forever */
116 STD_LOOP_COUNT = 1, /* number of iterations */
117 STD_COPIES = 1, /* number of copies */
118 STD_ERRNO_LOG = 0; /* flag indicating to do errno logging */
alaffincc2e5552000-07-27 17:13:18 +0000119
Wanlong Gao354ebb42012-12-07 10:10:04 +0800120float STD_LOOP_DURATION = 0.0, /* duration value in fractional seconds */
121 STD_LOOP_DELAY = 0.0; /* loop delay value in fractional seconds */
alaffincc2e5552000-07-27 17:13:18 +0000122
123char **STD_opt_arr = NULL; /* array of option strings */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800124int STD_nopts = 0, /* number of elements in STD_opt_arr */
125 STD_argind = 1; /* argv index to next argv element */
alaffincc2e5552000-07-27 17:13:18 +0000126 /* (first argument) */
127 /* To getopt users, it is like optind */
128
129/*
130 * The following variables are to support system testing additions.
131 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800132static int STD_TP_barrier = 0; /* flag to do barrier in TEST_PAUSE */
alaffincc2e5552000-07-27 17:13:18 +0000133 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134static int STD_LP_barrier = 0; /* flag to do barrier in TEST_LOOPING */
alaffincc2e5552000-07-27 17:13:18 +0000135 /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800136static int STD_TP_shmem_sz = 0; /* shmalloc this many words per pe in TEST_PAUSE */
137static int STD_LD_shmem = 0; /* flag to do shmem_puts and shmem_gets during delay */
138static int STD_LP_shmem = 0; /* flag to do shmem_puts and gets during TEST_LOOPING */
139static int STD_LD_recfun = 0; /* do recressive function calls in loop delay */
140static int STD_LP_recfun = 0; /* do recressive function calls in TEST_LOOPING */
141static int STD_TP_sbrk = 0; /* do sbrk in TEST_PAUSE */
142static int STD_LP_sbrk = 0; /* do sbrk in TEST_LOOPING */
143static char *STD_start_break = 0; /* original sbrk size */
144static int Debug = 0;
alaffincc2e5552000-07-27 17:13:18 +0000145
nstraz94181082000-08-30 18:43:38 +0000146struct std_option_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800147 char *optstr;
148 char *help;
149 char *flag;
150 char **arg;
nstraz94181082000-08-30 18:43:38 +0000151} std_options[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800152 {
153 "c:", " -c n Run n copies concurrently\n", NULL, NULL}, {
154 "e", " -e Turn on errno logging\n", NULL, NULL}, {
155 "f", " -f Turn off functional testing\n", NULL, NULL}, {
156 "h", " -h Show this help screen\n", NULL, NULL}, {
157 "i:", " -i n Execute test n times\n", NULL, NULL}, {
158 "I:", " -I x Execute test for x seconds\n", NULL, NULL}, {
159 "p", " -p Pause for SIGUSR1 before starting\n", NULL, NULL}, {
160 "P:", " -P x Pause for x seconds between iterations\n", NULL, NULL},
161 {
162 "t", " -t Turn on syscall timing\n", NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000163#ifdef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800164 {
165 "C:",
166 " -C ARG Run the child process with arguments ARG (for internal use)\n",
167 NULL, NULL},
robbiewd34d5812005-07-11 22:28:09 +0000168#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800169 {
170NULL, NULL, NULL, NULL}};
nstraz94181082000-08-30 18:43:38 +0000171
Wanlong Gao354ebb42012-12-07 10:10:04 +0800172void print_help(void (*user_help) ());
nstraz94181082000-08-30 18:43:38 +0000173
alaffincc2e5552000-07-27 17:13:18 +0000174/*
175 * Structure for usc_recressive_func argument
176 */
177struct usc_bigstack_t {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178 char space[4096];
alaffincc2e5552000-07-27 17:13:18 +0000179};
180
Wanlong Gao354ebb42012-12-07 10:10:04 +0800181static struct usc_bigstack_t *STD_bigstack = NULL;
alaffincc2e5552000-07-27 17:13:18 +0000182
alaffincc2e5552000-07-27 17:13:18 +0000183/*
184 * Counter of errnos returned (-e option). Indexed by errno.
185 * Make the array USC_MAX_ERRNO long. That is the first Fortran
186 * Lib errno. No syscall should return an errno that high.
187 */
188int STD_ERRNO_LIST[USC_MAX_ERRNO];
189
190/* define the string length for Mesg and Mesg2 strings */
191#define STRLEN 2048
192
alaffincc2e5552000-07-27 17:13:18 +0000193static char Mesg2[STRLEN]; /* holds possible return string */
194static void usc_recressive_func();
195
196/*
197 * Define bits for options that might have env variable default
198 */
199#define OPT_iteration 01
200#define OPT_nofunccheck 02
201#define OPT_duration 04
202#define OPT_delay 010
203#define OPT_copies 020
204
robbiewd34d5812005-07-11 22:28:09 +0000205#ifdef UCLINUX
206/* Allocated and used in self_exec.c: */
207extern char *child_args; /* Arguments to child when -C is used */
208#endif
alaffincc2e5552000-07-27 17:13:18 +0000209
210/**********************************************************************
vapier45a8ba02009-07-20 10:59:32 +0000211 * parse_opts:
alaffincc2e5552000-07-27 17:13:18 +0000212 **********************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800213char *parse_opts(int ac, char **av, const option_t * user_optarr,
214 void (*uhf) ())
alaffincc2e5552000-07-27 17:13:18 +0000215{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800216 int found; /* flag to indicate that an option specified was */
217 /* found in the user's list */
218 int k; /* scratch integer for returns and short time usage */
219 float ftmp; /* tmp float for parsing env variables */
220 char *ptr; /* used in getting env variables */
221 int options = 0; /* no options specified */
222 int optstrlen, i;
223 char *optionstr;
224 int opt; /* return of getopt */
alaffincc2e5552000-07-27 17:13:18 +0000225
Wanlong Gao354ebb42012-12-07 10:10:04 +0800226 /*
227 * If not the first time this function is called, release the old STD_opt_arr
228 * vector.
229 */
alaffincc2e5552000-07-27 17:13:18 +0000230
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800231#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
Wanlong Gao354ebb42012-12-07 10:10:04 +0800232 spawned_program_pid = getpid();
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -0800233#endif
234
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 if (STD_opt_arr != NULL) {
236 free(STD_opt_arr);
237 STD_opt_arr = NULL;
nstraz94181082000-08-30 18:43:38 +0000238 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800239 /* Calculate how much space we need for the option string */
240 optstrlen = 0;
241 for (i = 0; std_options[i].optstr; ++i)
242 optstrlen += strlen(std_options[i].optstr);
243 if (user_optarr)
244 for (i = 0; user_optarr[i].option; ++i) {
245 if (strlen(user_optarr[i].option) > 2)
246 return
247 "parse_opts: ERROR - Only short options are allowed";
248 optstrlen += strlen(user_optarr[i].option);
249 }
250 optstrlen += 1;
alaffincc2e5552000-07-27 17:13:18 +0000251
Wanlong Gao354ebb42012-12-07 10:10:04 +0800252 /* Create the option string for getopt */
253 optionstr = malloc(optstrlen);
254 if (!optionstr)
255 return
256 "parse_opts: ERROR - Could not allocate memory for optionstr";
alaffincc2e5552000-07-27 17:13:18 +0000257
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 optionstr[0] = '\0';
nstraz829b40a2000-09-06 14:33:29 +0000259
Wanlong Gao354ebb42012-12-07 10:10:04 +0800260 for (i = 0; std_options[i].optstr; ++i)
261 strcat(optionstr, std_options[i].optstr);
262 if (user_optarr)
263 for (i = 0; user_optarr[i].option; ++i)
264 /* only add the option if it wasn't there already */
265 if (strchr(optionstr, user_optarr[i].option[0]) == NULL)
266 strcat(optionstr, user_optarr[i].option);
alaffincc2e5552000-07-27 17:13:18 +0000267
268#if DEBUG > 1
Wanlong Gao354ebb42012-12-07 10:10:04 +0800269 printf("STD_nopts = %d\n", STD_nopts);
alaffincc2e5552000-07-27 17:13:18 +0000270#endif
271
Wanlong Gao354ebb42012-12-07 10:10:04 +0800272 /*
273 * Loop through av parsing options.
274 */
275 while ((opt = getopt(ac, av, optionstr)) > 0) {
alaffincc2e5552000-07-27 17:13:18 +0000276
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 STD_argind = optind;
alaffincc2e5552000-07-27 17:13:18 +0000278#if DEBUG > 0
Wanlong Gao354ebb42012-12-07 10:10:04 +0800279 printf("parse_opts: getopt returned '%c'\n", opt);
alaffincc2e5552000-07-27 17:13:18 +0000280#endif
alaffincc2e5552000-07-27 17:13:18 +0000281
Wanlong Gao354ebb42012-12-07 10:10:04 +0800282 switch (opt) {
283 case '?': /* Unknown option */
nstraz94181082000-08-30 18:43:38 +0000284 return "Unknown option";
285 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800286 case ':': /* Missing Arg */
nstraz94181082000-08-30 18:43:38 +0000287 return "Missing argument";
288 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800289 case 'i': /* Iterations */
nstraz94181082000-08-30 18:43:38 +0000290 options |= OPT_iteration;
291 STD_LOOP_COUNT = atoi(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800292 if (STD_LOOP_COUNT == 0)
293 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000294 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800295 case 'P': /* Delay between iterations */
nstraz94181082000-08-30 18:43:38 +0000296 options |= OPT_delay;
297 STD_LOOP_DELAY = atof(optarg);
298 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800299 case 'I': /* Time duration */
nstraz94181082000-08-30 18:43:38 +0000300 options |= OPT_duration;
301 STD_LOOP_DURATION = atof(optarg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800302 if (STD_LOOP_DURATION == 0.0)
303 STD_INFINITE = 1;
nstraz94181082000-08-30 18:43:38 +0000304 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800305 case 'c': /* Copies */
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100306 fprintf(stderr,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800307 "WARNING * WARNING * WARNING * WARNING * "
308 "WARNING * WARNING * WARNING * WARNING\n\n"
309 "The -c option is broken by desing. See:\n\n"
310 "http://www.mail-archive.com/"
311 "ltp-list@lists.sourceforge.net/msg13418.html\n"
312 "\nIn short don't use it in runtest files "
313 "as the option will be removed.\n\n"
Cyril Hrubis2ef059e2012-02-02 15:53:07 +0100314 "WARNING * WARNING * WARNING * WARNING * "
315 "WARNING * WARNING * WARNING * WARNING\n\n");
nstraz94181082000-08-30 18:43:38 +0000316 options |= OPT_copies;
317 STD_COPIES = atoi(optarg);
318 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800319 case 'f': /* Functional testing */
nstraz94181082000-08-30 18:43:38 +0000320 STD_FUNCTIONAL_TEST = 0;
321 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800322 case 'p': /* Pause for SIGUSR1 */
nstraz94181082000-08-30 18:43:38 +0000323 STD_PAUSE = 1;
324 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800325 case 't': /* syscall timing */
nstraz94181082000-08-30 18:43:38 +0000326 STD_TIMING_ON = 1;
327 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800328 case 'e': /* errno loggin */
nstraz94181082000-08-30 18:43:38 +0000329 STD_ERRNO_LOG = 1;
330 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800331 case 'h': /* Help */
nstraz94181082000-08-30 18:43:38 +0000332 print_help(uhf);
333 exit(0);
334 break;
robbiewd34d5812005-07-11 22:28:09 +0000335#ifdef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800336 case 'C': /* Run child */
robbiewd34d5812005-07-11 22:28:09 +0000337 child_args = optarg;
338 break;
339#endif
nstraz94181082000-08-30 18:43:38 +0000340 default:
vapier45a8ba02009-07-20 10:59:32 +0000341
Wanlong Gao354ebb42012-12-07 10:10:04 +0800342 /* Check all the user specified options */
343 found = 0;
344 for (i = 0; user_optarr[i].option; ++i) {
alaffincc2e5552000-07-27 17:13:18 +0000345
Wanlong Gao354ebb42012-12-07 10:10:04 +0800346 if (opt == user_optarr[i].option[0]) {
347 /* Yup, This is a user option, set the flag and look for argument */
348 if (user_optarr[i].flag) {
349 *user_optarr[i].flag = 1;
350 }
351 found++;
alaffincc2e5552000-07-27 17:13:18 +0000352
Wanlong Gao354ebb42012-12-07 10:10:04 +0800353 /* save the argument at the user's location */
354 if (user_optarr[i].
355 option[strlen(user_optarr[i].option)
356 - 1] == ':') {
357 *user_optarr[i].arg = optarg;
358 }
359 break; /* option found - break out of the for loop */
360 }
361 }
362 /* This condition "should never happen". SO CHECK FOR IT!!!! */
363 if (!found) {
364 sprintf(Mesg2,
365 "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL "
366 "ERROR", opt);
367 return (Mesg2);
368 }
369 }
370
371 } /* end of while */
372 free(optionstr);
373
374 STD_argind = optind;
375
376 /*
377 * Turn on debug
378 */
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200379 if (getenv("USC_DEBUG") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800380 Debug = 1;
381 printf("env USC_DEBUG is defined, turning on debug\n");
382 }
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200383 if (getenv("USC_VERBOSE") != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800384 Debug = 1;
385 printf("env USC_VERBOSE is defined, turning on debug\n");
alaffincc2e5552000-07-27 17:13:18 +0000386 }
387
Wanlong Gao354ebb42012-12-07 10:10:04 +0800388 /*
389 * If the USC_ITERATION_ENV environmental variable is set to
390 * a number, use that number as iteration count (same as -c option).
391 * The -c option with arg will be used even if this env var is set.
392 */
393 if (!(options & OPT_iteration)
394 && (ptr = getenv(USC_ITERATION_ENV)) != NULL) {
395 if (sscanf(ptr, "%i", &k) == 1) {
396 if (k == 0) { /* if arg is 0, set infinite loop flag */
397 STD_INFINITE = 1;
398 if (Debug)
399 printf
400 ("Using env %s, set STD_INFINITE to 1\n",
401 USC_ITERATION_ENV);
402 } else { /* else, set the loop count to the arguement */
403 STD_LOOP_COUNT = k;
404 if (Debug)
405 printf
406 ("Using env %s, set STD_LOOP_COUNT to %d\n",
407 USC_ITERATION_ENV, k);
408 }
409 }
410 }
alaffincc2e5552000-07-27 17:13:18 +0000411
Wanlong Gao354ebb42012-12-07 10:10:04 +0800412 /*
413 * If the USC_NO_FUNC_CHECK environmental variable is set, we'll
414 * unset the STD_FUNCTIONAL_TEST variable.
415 */
416 if (!(options & OPT_nofunccheck) &&
Cyril Hrubis8dc262a2013-06-04 19:12:59 +0200417 getenv(USC_NO_FUNC_CHECK) != NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800418 STD_FUNCTIONAL_TEST = 0; /* Turn off functional testing */
Garrett Cooper903910d2010-11-23 09:27:44 -0800419 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800420 printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
421 USC_NO_FUNC_CHECK);
422 }
423
424 /*
425 * If the USC_LOOP_WALLTIME environmental variable is set,
426 * use that number as duration (same as -I option).
427 * The -I option with arg will be used even if this env var is set.
428 */
429
430 if (!(options & OPT_duration) &&
431 (ptr = getenv(USC_LOOP_WALLTIME)) != NULL) {
432 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
433 STD_LOOP_DURATION = ftmp;
434 if (Debug)
435 printf
436 ("Using env %s, set STD_LOOP_DURATION to %f\n",
437 USC_LOOP_WALLTIME, ftmp);
438 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
439 STD_INFINITE = 1;
440 if (Debug)
441 printf
442 ("Using env %s, set STD_INFINITE to 1\n",
443 USC_LOOP_WALLTIME);
444 }
445 }
446 }
447 if (!(options & OPT_duration) && (ptr = getenv("USC_DURATION")) != NULL) {
448 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
449 STD_LOOP_DURATION = ftmp;
450 if (Debug)
451 printf
452 ("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n",
453 ftmp);
454 if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
455 STD_INFINITE = 1;
456 if (Debug)
457 printf
458 ("Using env USC_DURATION, set STD_INFINITE to 1\n");
459 }
460 }
461 }
462 /*
463 * If the USC_LOOP_DELAY environmental variable is set,
464 * use that number as delay in factional seconds (same as -P option).
465 * The -P option with arg will be used even if this env var is set.
466 */
467 if (!(options & OPT_delay) && (ptr = getenv(USC_LOOP_DELAY)) != NULL) {
468 if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
469 STD_LOOP_DELAY = ftmp;
470 if (Debug)
471 printf
472 ("Using env %s, set STD_LOOP_DELAY = %f\n",
473 USC_LOOP_DELAY, ftmp);
474 }
475 }
476
477 /*
478 * If the USC_COPIES environmental variable is set,
479 * use that number as copies (same as -c option).
480 * The -c option with arg will be used even if this env var is set.
481 */
482 if (!(options & OPT_copies) && (ptr = getenv(USC_COPIES)) != NULL) {
483 if (sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0) {
484 if (Debug)
485 printf("Using env %s, set STD_COPIES = %d\n",
486 USC_COPIES, STD_COPIES);
487 }
488 }
489
490 /*
491 * The following are special system testing envs to turn on special
492 * hooks in the code.
493 */
494 if ((ptr = getenv("USC_TP_BARRIER")) != NULL) {
495 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
496 STD_TP_barrier = k;
497 else
498 STD_TP_barrier = 1;
Garrett Cooper903910d2010-11-23 09:27:44 -0800499 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800500 printf
501 ("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
502 STD_TP_barrier);
503 }
alaffincc2e5552000-07-27 17:13:18 +0000504
Wanlong Gao354ebb42012-12-07 10:10:04 +0800505 if ((ptr = getenv("USC_LP_BARRIER")) != NULL) {
506 if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
507 STD_LP_barrier = k;
508 else
509 STD_LP_barrier = 1;
510 if (Debug)
511 printf
512 ("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
513 STD_LP_barrier);
514 }
alaffincc2e5552000-07-27 17:13:18 +0000515
Wanlong Gao354ebb42012-12-07 10:10:04 +0800516 if ((ptr = getenv("USC_TP_SHMEM")) != NULL) {
517 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
518 STD_TP_shmem_sz = k;
519 if (Debug)
520 printf
521 ("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
522 STD_TP_shmem_sz);
523 }
524 }
alaffincc2e5552000-07-27 17:13:18 +0000525
Wanlong Gao354ebb42012-12-07 10:10:04 +0800526 if ((ptr = getenv("USC_LP_SHMEM")) != NULL) {
527 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
528 STD_LP_shmem = k;
529 if (Debug)
530 printf
531 ("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
532 STD_LP_shmem);
533 }
534 }
alaffincc2e5552000-07-27 17:13:18 +0000535
Wanlong Gao354ebb42012-12-07 10:10:04 +0800536 if ((ptr = getenv("USC_LD_SHMEM")) != NULL) {
537 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
538 STD_LD_shmem = k;
539 if (Debug)
540 printf
541 ("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
542 STD_LD_shmem);
543 }
544 }
alaffincc2e5552000-07-27 17:13:18 +0000545
Wanlong Gao354ebb42012-12-07 10:10:04 +0800546 if ((ptr = getenv("USC_TP_SBRK")) != NULL) {
547 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
548 STD_TP_sbrk = k;
549 if (Debug)
550 printf
551 ("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
552 STD_TP_sbrk);
553 }
554 }
robbiewd34d5812005-07-11 22:28:09 +0000555#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800556 if ((ptr = getenv("USC_LP_SBRK")) != NULL) {
557 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
558 STD_LP_sbrk = k;
559 if (Debug)
560 printf
561 ("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
562 STD_LP_sbrk);
563 }
564 }
robbiewd34d5812005-07-11 22:28:09 +0000565#endif /* if !defined(UCLINUX) */
alaffincc2e5552000-07-27 17:13:18 +0000566
Wanlong Gao354ebb42012-12-07 10:10:04 +0800567 if ((ptr = getenv("USC_LP_RECFUN")) != NULL) {
568 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
569 STD_LP_recfun = k;
570 if (STD_bigstack != NULL)
571 STD_bigstack =
572 malloc(sizeof(struct usc_bigstack_t));
573 if (Debug)
574 printf
575 ("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
576 STD_LP_recfun);
577 }
578 }
alaffincc2e5552000-07-27 17:13:18 +0000579
Wanlong Gao354ebb42012-12-07 10:10:04 +0800580 if ((ptr = getenv("USC_LD_RECFUN")) != NULL) {
581 if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
582 STD_LD_recfun = k;
583 if (STD_bigstack != NULL)
584 STD_bigstack =
585 malloc(sizeof(struct usc_bigstack_t));
586 if (Debug)
587 printf
588 ("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
589 STD_LD_recfun);
590 }
591 }
alaffincc2e5552000-07-27 17:13:18 +0000592#if UNIT_TEST
Wanlong Gao354ebb42012-12-07 10:10:04 +0800593 printf("The following variables after option and env parsing:\n");
594 printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
595 printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION);
596 printf("STD_LOOP_DELAY = %f\n", STD_LOOP_DELAY);
597 printf("STD_COPIES = %d\n", STD_COPIES);
598 printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT);
599 printf("STD_INFINITE = %d\n", STD_INFINITE);
600 printf("STD_TIMING_ON = %d\n", STD_TIMING_ON);
601 printf("STD_ERRNO_LOG = %d\n", STD_ERRNO_LOG);
602 printf("STD_PAUSE = %d\n", STD_PAUSE);
alaffincc2e5552000-07-27 17:13:18 +0000603#endif
604
Wanlong Gao354ebb42012-12-07 10:10:04 +0800605 return ((char *)NULL);
alaffincc2e5552000-07-27 17:13:18 +0000606
Wanlong Gao354ebb42012-12-07 10:10:04 +0800607} /* end of parse_opts */
alaffincc2e5552000-07-27 17:13:18 +0000608
alaffincc2e5552000-07-27 17:13:18 +0000609/*********************************************************************
nstraz94181082000-08-30 18:43:38 +0000610 * print_help() - print help message and user help message
alaffincc2e5552000-07-27 17:13:18 +0000611 *********************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800612void print_help(void (*user_help) ())
alaffincc2e5552000-07-27 17:13:18 +0000613{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800614 STD_opts_help();
alaffincc2e5552000-07-27 17:13:18 +0000615
Wanlong Gao354ebb42012-12-07 10:10:04 +0800616 if (user_help)
617 user_help();
alaffincc2e5552000-07-27 17:13:18 +0000618}
619
620/*********************************************************************
621 * STD_opts_help() - return a help string for the STD_OPTIONS.
622 *********************************************************************/
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800623void STD_opts_help()
alaffincc2e5552000-07-27 17:13:18 +0000624{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800625 int i;
alaffincc2e5552000-07-27 17:13:18 +0000626
Wanlong Gao354ebb42012-12-07 10:10:04 +0800627 for (i = 0; std_options[i].optstr; ++i) {
628 if (std_options[i].help)
629 printf("%s", std_options[i].help);
630 }
alaffincc2e5552000-07-27 17:13:18 +0000631}
632
vapier45a8ba02009-07-20 10:59:32 +0000633/*
alaffincc2e5552000-07-27 17:13:18 +0000634 * routine to goto when we get the SIGUSR1 for STD_PAUSE
635 */
636void STD_go(int sig)
637{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800638 return;
alaffincc2e5552000-07-27 17:13:18 +0000639}
640
641/***********************************************************************
642 * This function will do desired end of global setup test
643 * hooks.
644 * Currently it will only do a pause waiting for sigusr1 if
645 * STD_PAUSE is set.
646 *
647 ***********************************************************************/
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800648int usc_global_setup_hook()
alaffincc2e5552000-07-27 17:13:18 +0000649{
robbiewd34d5812005-07-11 22:28:09 +0000650#ifndef UCLINUX
Wanlong Gao354ebb42012-12-07 10:10:04 +0800651 int cnt;
652 /* temp variable to store old signal action to be restored after pause */
653 int (*_TMP_FUNC) (void);
alaffincc2e5552000-07-27 17:13:18 +0000654
Wanlong Gao354ebb42012-12-07 10:10:04 +0800655 /*
656 * Fork STD_COPIES-1 copies.
657 */
658 for (cnt = 1; cnt < STD_COPIES; cnt++) {
659 switch (fork()) {
660 case -1:
661 fprintf(stderr, "%s: fork failed: %d - %s\n",
662 __FILE__, errno, strerror(errno));
663 break;
664 case 0: /* child */
665 cnt = STD_COPIES; /* to stop the forking */
666 break;
alaffincc2e5552000-07-27 17:13:18 +0000667
Wanlong Gao354ebb42012-12-07 10:10:04 +0800668 default: /* parent */
669 break;
670 }
alaffincc2e5552000-07-27 17:13:18 +0000671 }
vapier45a8ba02009-07-20 10:59:32 +0000672
Wanlong Gao354ebb42012-12-07 10:10:04 +0800673 /*
674 * pause waiting for sigusr1.
675 */
676 if (STD_PAUSE) {
677 _TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);
678 pause();
679 signal(SIGUSR1, (void (*)())_TMP_FUNC);
680 }
robbiewd34d5812005-07-11 22:28:09 +0000681#if !defined(UCLINUX)
alaffincc2e5552000-07-27 17:13:18 +0000682
Wanlong Gao354ebb42012-12-07 10:10:04 +0800683 if (STD_TP_sbrk || STD_LP_sbrk) {
684 STD_start_break = sbrk(0); /* get original sbreak size */
685 }
alaffincc2e5552000-07-27 17:13:18 +0000686
Wanlong Gao354ebb42012-12-07 10:10:04 +0800687 if (STD_TP_sbrk) {
688 sbrk(STD_TP_sbrk);
689 if (Debug)
690 printf("after sbrk(%d)\n", STD_TP_sbrk);
691 }
robbiewd34d5812005-07-11 22:28:09 +0000692#endif /* if !defined(UCLINUX) */
693#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800694 return 0;
alaffincc2e5552000-07-27 17:13:18 +0000695}
696
Wanlong Gao354ebb42012-12-07 10:10:04 +0800697#define USECS_PER_SEC 1000000 /* microseconds per second */
alaffincc2e5552000-07-27 17:13:18 +0000698
699/***********************************************************************
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100700 * Returns current time in microseconds since 1970.
alaffincc2e5552000-07-27 17:13:18 +0000701 ***********************************************************************/
Cyril Hrubis4d964f62012-03-07 18:02:37 +0100702static uint64_t get_current_time(void)
alaffincc2e5552000-07-27 17:13:18 +0000703{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800704 struct timeval curtime;
alaffincc2e5552000-07-27 17:13:18 +0000705
Wanlong Gao354ebb42012-12-07 10:10:04 +0800706 gettimeofday(&curtime, NULL);
alaffincc2e5552000-07-27 17:13:18 +0000707
Wanlong Gao354ebb42012-12-07 10:10:04 +0800708 return (((uint64_t) curtime.tv_sec) * USECS_PER_SEC) + curtime.tv_usec;
alaffincc2e5552000-07-27 17:13:18 +0000709}
710
711/***********************************************************************
712 *
713 * This function will determine if test should continue iterating
714 * If the STD_INFINITE flag is set, return 1.
715 * If the STD_LOOP_COUNT variable is set, compare it against
716 * the counter.
717 * If the STD_LOOP_DURATION variable is set, compare current time against
718 * calculated stop_time.
719 * This function will return 1 until all desired looping methods
vapier45a8ba02009-07-20 10:59:32 +0000720 * have been met.
alaffincc2e5552000-07-27 17:13:18 +0000721 *
722 * counter integer is supplied by the user program.
723 ***********************************************************************/
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800724int usc_test_looping(int counter)
alaffincc2e5552000-07-27 17:13:18 +0000725{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800726 static int first_time = 1;
727 static uint64_t stop_time = 0;
728 static uint64_t delay;
729 uint64_t ct, end;
730 int keepgoing = 0;
alaffincc2e5552000-07-27 17:13:18 +0000731
732 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800733 * If this is the first iteration and we are looping for
734 * duration of STD_LOOP_DURATION seconds (fractional) or
735 * doing loop delays, get the clocks per second.
alaffincc2e5552000-07-27 17:13:18 +0000736 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800737 if (first_time) {
738 first_time = 0;
739
740 /*
741 * If looping for duration, calculate stop time in
742 * clocks.
743 */
744 if (STD_LOOP_DURATION) {
745 stop_time =
746 (uint64_t) (USECS_PER_SEC * STD_LOOP_DURATION)
747 + get_current_time();
748 }
749
750 /*
751 * If doing delay each iteration, calcuate the number
752 * of clocks for each delay.
753 */
754 if (STD_LOOP_DELAY)
755 delay = USECS_PER_SEC * STD_LOOP_DELAY;
alaffincc2e5552000-07-27 17:13:18 +0000756 }
757
758 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800759 * if delay each iteration, loop for delay clocks.
760 * This will not be done on first iteration.
761 * The delay will happen before determining if
762 * there will be another iteration.
alaffincc2e5552000-07-27 17:13:18 +0000763 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800764 else if (STD_LOOP_DELAY) {
765 ct = get_current_time();
766 end = ct + delay;
767 while (ct < end) {
768 /*
769 * The following are special test hooks in the delay loop.
770 */
771 if (STD_LD_recfun) {
772 if (Debug)
773 printf
774 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
775 STD_LD_recfun);
776 usc_recressive_func(0, STD_LD_recfun,
777 *STD_bigstack);
778 }
vapier45a8ba02009-07-20 10:59:32 +0000779
Wanlong Gao354ebb42012-12-07 10:10:04 +0800780 ct = get_current_time();
781 }
782 }
783
784 if (STD_INFINITE)
785 keepgoing++;
786
787 if (STD_LOOP_COUNT && counter < STD_LOOP_COUNT)
788 keepgoing++;
789
790 if (STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time)
791 keepgoing++;
792
793 if (keepgoing == 0)
794 return 0;
795
796 /*
797 * The following code allows special system testing hooks.
798 */
799
800 if (STD_LP_recfun) {
Garrett Cooper903910d2010-11-23 09:27:44 -0800801 if (Debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800802 printf
803 ("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
804 STD_LP_recfun);
805 usc_recressive_func(0, STD_LP_recfun, *STD_bigstack);
alaffincc2e5552000-07-27 17:13:18 +0000806 }
robbiewd34d5812005-07-11 22:28:09 +0000807#if !defined(UCLINUX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800808 if (STD_LP_sbrk) {
809 if (Debug)
810 printf("about to do sbrk(%d)\n", STD_LP_sbrk);
811 sbrk(STD_LP_sbrk);
812 }
robbiewd34d5812005-07-11 22:28:09 +0000813#endif
alaffincc2e5552000-07-27 17:13:18 +0000814
Wanlong Gao354ebb42012-12-07 10:10:04 +0800815 if (keepgoing)
816 return 1;
817 else
818 return 0; /* done - stop iterating */
alaffincc2e5552000-07-27 17:13:18 +0000819}
820
alaffincc2e5552000-07-27 17:13:18 +0000821/*
822 * This function recressively calls itself max times.
vapier45a8ba02009-07-20 10:59:32 +0000823 */
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800824static void usc_recressive_func(int cnt, int max, struct usc_bigstack_t bstack)
alaffincc2e5552000-07-27 17:13:18 +0000825{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800826 if (cnt < max)
827 usc_recressive_func(cnt + 1, max, bstack);
alaffincc2e5552000-07-27 17:13:18 +0000828
829}
830
831#if UNIT_TEST
832/******************************************************************************
833 * UNIT TEST CODE
834 * UNIT TEST CODE
vapier45a8ba02009-07-20 10:59:32 +0000835 *
alaffincc2e5552000-07-27 17:13:18 +0000836 * this following code is provide so that unit testing can
837 * be done fairly easily.
838 ******************************************************************************/
839
840int Help = 0;
841int Help2 = 0;
842char *ptr;
843
844/*
845 * Code from usctest.h that not part of this file since we are the library.
846 */
847
848struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
849
Markos Chandrasfd4ada72012-01-03 11:10:37 +0000850long TEST_RETURN;
alaffincc2e5552000-07-27 17:13:18 +0000851int TEST_ERRNO;
852
alaffincc2e5552000-07-27 17:13:18 +0000853/* for test specific parse_opts options */
854option_t Options[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800855 {"help", &Help2, NULL}, /* -help option */
856 {"h", &Help, NULL}, /* -h option */
alaffincc2e5552000-07-27 17:13:18 +0000857
858#if INVALID_TEST_CASES
Wanlong Gao354ebb42012-12-07 10:10:04 +0800859 {"missingflag", NULL, &ptr}, /* error */
860 {"missingarg:", &Help, NULL}, /* error */
861#endif /* INVALID_TEST_CASES */
alaffincc2e5552000-07-27 17:13:18 +0000862
Wanlong Gao354ebb42012-12-07 10:10:04 +0800863 {NULL, NULL, NULL}
alaffincc2e5552000-07-27 17:13:18 +0000864};
865
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800866int main(int argc, char **argv)
alaffincc2e5552000-07-27 17:13:18 +0000867{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800868 int lc;
869 char *msg;
870 struct timeval t;
871 int cnt;
alaffincc2e5552000-07-27 17:13:18 +0000872
Wanlong Gao354ebb42012-12-07 10:10:04 +0800873 if ((msg = parse_opts(argc, argv, Options, NULL)) != NULL) {
874 printf("ERROR: %s\n", msg);
875 exit(1);
876 }
alaffincc2e5552000-07-27 17:13:18 +0000877
Wanlong Gao354ebb42012-12-07 10:10:04 +0800878 TEST_PAUSE;
alaffincc2e5552000-07-27 17:13:18 +0000879
Wanlong Gao354ebb42012-12-07 10:10:04 +0800880 for (lc = 0; TEST_LOOPING(lc); lc++) {
vapier45a8ba02009-07-20 10:59:32 +0000881
Wanlong Gao354ebb42012-12-07 10:10:04 +0800882 TEST(gettimeofday(&t, NULL));
883 printf("iter=%d: sec:%d, usec:%6.6d %s", lc + 1, t.tv_sec,
884 t.tv_usec, ctime(&t.tv_sec));
885 }
alaffincc2e5552000-07-27 17:13:18 +0000886
Wanlong Gao354ebb42012-12-07 10:10:04 +0800887 TEST_CLEANUP;
alaffincc2e5552000-07-27 17:13:18 +0000888
Wanlong Gao354ebb42012-12-07 10:10:04 +0800889 exit(0);
alaffincc2e5552000-07-27 17:13:18 +0000890}
891
Garrett Cooper8b02c1c2011-01-26 01:34:49 -0800892#endif /* UNIT_TEST */