1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 /*---------------------------------------------------------------------+
19 | sched_driver |
20 | ==================================================================== |
21 | |
22 | Description: This program uses system calls to change the |
23 | priorities of the throughput measurement testcases. |
24 | When real-time is in effect, priorities 50 through 64 |
25 | are used. (MAX_PRI and MIN_PRI) When user-time |
26 | (normal) is in effect, 0-14 (corresponding to nice() |
27 | calls) is used. The driver only keeps track of |
28 | values from 50 to 64, and the testcases will scale |
29 | them down to 0 to 14 when needed, to change the |
30 | priority of a user-time process. |
31 | |
32 | Algorithm: o Parse command line arguments |
33 | o Set current priority |
34 | o Calcucations (process slots, short/long term slots) |
35 | o Perform throughput tests with high priority |
36 | o Start long-term testcases |
37 | o While time remains |
38 | - Start short-term tests |
39 | - Perform throughput tests with new priority |
40 | - Kill short-term tests |
41 | - Increase priority |
42 | |
43 | Usage: sched_driver [-s n] [-p n] [-t n] [-d] [-v] |
44 | |
45 | where: |
46 | -s n stress percentage |
47 | -p n process slots |
48 | -t n execution time in hours |
49 | -d enable debugging messages |
50 | -v Turn on verbose mode |
51 | |
52 | Last update: Ver. 1.15, 4/10/94 23:04:23 |
53 | |
54 | Change Activity |
55 | |
56 | Version Date Name Reason |
57 | 0.1 072889 GEB Initial draft |
58 | 1.2 120793 JAT Changes for AIX 4.1 |
59 | 1.3 041094 DJK Rewrote protions... |
60 | 1.4 010402 Manoj Iyer Ported to Linux |
61 | |
62 +---------------------------------------------------------------------*/
63
64 #include <sys/types.h>
65 #include <unistd.h>
66 #include <sys/wait.h>
67 #include <string.h>
68 #include <stdlib.h>
69 #include <signal.h>
70 #include <pwd.h>
71 #include <time.h>
72 #include <limits.h>
73 #include "sched.h"
74
75 /*
76 * Defines:
77 *
78 * MAXPROCS: maximum number of processes
79 *
80 * PRIINC: priority step value
81 *
82 * MAX_PRI: highest priority to use
83 *
84 * MIN_PRI: lowest priority to use
85 *
86 * DEFAULT_STRESS_PERCENTAGE: stress percentage (process slot multiplier)
87 *
88 * DEFAULT_PROCESS_SLOTS: number of processes test driver will try and create
89 *
90 * DEFAULT_TIME: time (hours) for which this test driver will run
91 *
92 * USAGE: usage statement
93 */
94 #define MAXPROCS 100
95 #define PRIINC 2
96 #define MAX_PRI 55 /* was 50 */
97 #define MIN_PRI 75 /* was 64 */
98 #define DEFAULT_STRESS_PERCENTAGE 0.5
99 #define DEFAULT_PROCESS_SLOTS 16
100 #define DEFAULT_TIME 1.00
101 #define USAGE "Usage: %s [-s n] [-p n] [-t n] [-d] [-v] \n" \
102 " -s n stress percentage [0.0<n<1.0] (default 0.5) \n" \
103 " -p n process slots (default 16) \n" \
104 " -t n execution time in hours (default 1.0 hrs) \n" \
105 " -d enable debugging messages \n" \
106 " -v Turn on verbose mode \n"
107
108 /*
109 * Global variables:
110 *
111 * stress_percent: stress percentage
112 *
113 * :
114 *
115 * execution_time: execution time in hours
116 *
117 * debug: (option flag) enables debugging messages
118 */
119 int numprocs, /* number of process id's in table */
120 procs[MAXPROCS], /* array of process id's for killing */
121 long_running, /* number of long term testcases running */
122 short_running; /* number of short term testcases running */
123 float e4user, /* previous elapsed seconds for tc 4-user */
124 e4real, /* previous elapsed seconds for tc 4-real */
125 e5user, /* previous elapsed seconds for tc 5-user */
126 e5real, /* previous elapsed seconds for tc 5-real */
127 e6user0, /* previous elapsed seconds for tc 6-user,nf */
128 e6real0, /* previous elapsed seconds for tc 6-real,nf */
129 e6user1, /* previous elapsed seconds for tc 6-user,f */
130 e6child; /* previous elapsed seconds for tc 6-child */
131 double stress_percent = DEFAULT_STRESS_PERCENTAGE;
132 double execution_time = DEFAULT_TIME;
133 int process_slots = DEFAULT_PROCESS_SLOTS;
134 int debug = 0;
135
136 /*
137 * Function prototypes
138 */
139 void startup(long);
140 int start_testcase(char *, char *, char *, char *, char *, char *);
141 int process_slots_in_use();
142 int available_user_process_slots();
143 float measure_test(char *, char *, char *, char *, float *);
144 void display_line(char *, int, int, float, float *, int);
145 void perform_throughput_tests(int);
146 void start_long_term_testcases(int, char *);
147 void kill_short_term_testcases();
148 void start_short_term_testcases(int, double, int);
149 void finishup(long);
150 void parse_args(int, char **);
151
152 /*---------------------------------------------------------------------+
153 | main () |
154 | ==================================================================== |
155 | |
156 | Function: Main program |
157 | |
158 +---------------------------------------------------------------------*/
main(int argc,char ** argv)159 int main(int argc, char **argv)
160 {
161 long runseconds, /* number of seconds to run */
162 start_time; /* time at start of driver */
163 int current_priority, /* current priority level for nice */
164 workslots, /* number of free workslots */
165 long_term_slot_total, /* workslots for long-term processes */
166 short_term_slot_total; /* workslots for short-term */
167
168 /*
169 * Parse command line arguments & printer program header...
170 */
171 parse_args(argc, argv);
172 printf("Scheduler Testsuite Program\n\n");
173 fflush(stdout);
174
175 /*
176 * Calculate number of seconds to run, then print out start info
177 */
178 runseconds = (long)(execution_time * 60.0 * 60.0);
179 start_time = time(NULL);
180
181 startup(start_time);
182
183 /*
184 * Calculate available workslots, long-term, and short-term slots
185 */
186 workslots = available_user_process_slots() * stress_percent;
187 long_term_slot_total = workslots / 2;
188 if (debug) {
189 printf("available slots: %d\n",
190 available_user_process_slots());
191 printf("workslots available: %d\n", workslots);
192 printf("stress_percent: %f\n", stress_percent);
193 printf("run-hours: %f (hrs)\n", execution_time);
194 printf("runseconds: %ld (sec)\n", runseconds);
195 }
196
197 /*
198 * Run the first set of tests with an average priority
199 */
200 perform_throughput_tests((MAX_PRI + MIN_PRI) / 2);
201 fflush(stdout);
202
203 /*
204 * Start the long-term testcases running
205 */
206 start_long_term_testcases(long_term_slot_total, argv[2]);
207 short_term_slot_total = workslots / 2;
208 fflush(stdout);
209
210 /*
211 * Loop while there is still time
212 */
213 current_priority = MAX_PRI;
214 while ((time(0) - start_time) < runseconds) {
215
216 if (debug)
217 printf("current priority: %d\n", current_priority);
218 if (debug)
219 printf("starting short term tests\n");
220
221 start_short_term_testcases(short_term_slot_total,
222 stress_percent, current_priority);
223 fflush(stdout);
224
225 perform_throughput_tests(current_priority);
226 fflush(stdout);
227
228 if (debug)
229 printf("killing short term tests\n");
230
231 kill_short_term_testcases();
232 fflush(stdout);
233
234 if (current_priority + PRIINC > MIN_PRI)
235 current_priority = MAX_PRI;
236 else
237 current_priority += PRIINC;
238 }
239
240 /*
241 * Exit with success...
242 */
243 finishup(start_time);
244 printf("\nsuccessful!\n");
245 fflush(stdout);
246 return (0);
247 }
248
249 /*------------------------------ startup() ------------------------------*/
250 /* This procedure opens the , and then outputs some starting *
251 * information to the screen and . It also initializes the *
252 * process id list and other global variables. *
253 *-----------------------------------------------------------------------*/
startup(long start_time)254 void startup(long start_time)
255 {
256 char tempbuffer[50]; /* temporary buffer to hold names */
257
258 /*
259 * Now output some diagnostic information
260 */
261 printf("start time = %s\n", ctime(&start_time));
262
263 gethostname(tempbuffer, 40);
264 printf("host name = %s\n", tempbuffer);
265
266 printf("user name = %s\n", getpwuid(geteuid())->pw_name);
267
268 printf("test duration = %4.2f (hours)\n", execution_time);
269
270 printf("test stress = %4.2f%%%%\n\n", 100 * stress_percent);
271
272 /*
273 * Initialize the global variables
274 */
275 numprocs = 0;
276 long_running = 0;
277 short_running = 0;
278 e4user = 0.0;
279 e4real = 0.0;
280 e5user = 0.0;
281 e5real = 0.0;
282 e6user0 = 0.0;
283 e6real0 = 0.0;
284 e6user1 = 0.0;
285 e6child = 0.0;
286 }
287
288 /*--------------------------- start_testcase() --------------------------*/
289 /* This procedure will run a specified testcase by forking a process, and*
290 * then running the testcase with it. It will also store the process id *
291 * number in the process id table. The process id of the child process *
292 * is returned to the calling program. *
293 * name1 pathname of testcase to run *
294 * name2 filename of testcase to run *
295 * param1 parameters to pass to the testcase *
296 * param2 *
297 * param3 *
298 * param4 if sched_tc6: fork flag: 0=false, 1=true *
299 *-----------------------------------------------------------------------*/
300
start_testcase(char * name1,char * name2,char * param1,char * param2,char * param3,char * param4)301 int start_testcase(char *name1, char *name2, char *param1, char *param2,
302 char *param3, char *param4)
303 {
304 int pid, /* pid of currently running process */
305 pid_save; /* saved pid of process */
306
307 /*
308 * Fork a process that will run testcase and save the pid
309 */
310 if (debug)
311 printf("test: %s %s p1[%s] p2[%s] p3[%s] p4[%s]\n",
312 name1, name2, param1, param2, param3, param4);
313
314 pid_save = pid = fork();
315
316 /*
317 * If the pid returned is -1, fork failed. If the pid returned is
318 * 0, then the process running is the child process, and we need
319 * to do an 'execl' to run the testcase. If the pid returned is
320 * anything else, then the parent is running, and we return.
321 */
322 switch (pid) {
323 case -1:
324 exit(-1);
325 case 0:
326 execl(name1, name2, param1, param2, param3, param4, NULL);
327 printf("ERROR: start_testcase(): execl failed.\n");
328 exit(-1);
329 default:
330 break;
331 }
332 if (debug)
333 printf("testcase %s started -- pid is %d\n", name2, pid_save);
334
335 /*
336 * If the process just forked is for a short-term testcase, then
337 * add the process id to the table.
338 */
339 if (debug)
340 printf("new process: %s ", name2);
341 if (strstr(name2, "tc1") || strstr(name2, "tc3")) {
342 procs[numprocs] = pid_save;
343 numprocs++;
344 short_running++;
345 if (debug)
346 printf("(%d short term)", short_running);
347 }
348 if (strstr(name2, "tc0") || strstr(name2, "tc2")) {
349 long_running++;
350 if (debug)
351 printf("(%d long term)", long_running);
352 }
353 if (debug)
354 printf("\n");
355
356 return (pid_save);
357 }
358
359 /*------------------------- process_slots_in_use() ----------------------*/
360 /* This function will return the number of process slots currently in use*
361 * by executing the 'ps' command. *
362 *-----------------------------------------------------------------------*/
process_slots_in_use()363 int process_slots_in_use()
364 {
365 FILE *psfile; /* temporary file to hold output of 'ps' command */
366 int usedslots; /* holds the number of used process slots */
367
368 /*
369 * Call the 'ps' command and write the number of process slots to a file
370 */
371 if (system("ps -e | wc -l > ps.out") < 0)
372 sys_error("system failed", __FILE__, __LINE__);
373
374 /*
375 * Open the output file
376 */
377 if ((psfile = fopen("ps.out", "r")) == NULL) {
378 exit(-1);
379 }
380
381 /*
382 * Read the number of process slots in use from the file
383 */
384 fscanf(psfile, "%d", &usedslots);
385
386 /*
387 * Close the output file
388 */
389 if (fclose(psfile) == -1) {
390 exit(-1);
391 }
392
393 /*
394 * Remove the output file
395 */
396 if (system("/bin/rm ps.out") < 0)
397 sys_error("system failed", __FILE__, __LINE__);
398
399 return (usedslots - 1);
400 }
401
402 /*----------------------- available_user_process_slots() ----------------*/
403 /* This function returns the total number of available user process slots*
404 * by subtracting the process slots currently in use from the maximum *
405 * possible process slots. *
406 *-----------------------------------------------------------------------*/
available_user_process_slots()407 int available_user_process_slots()
408 {
409 int num = process_slots_in_use();
410
411 return ((process_slots < num) ? process_slots : process_slots - num);
412 }
413
414 /*---------------------------- measure_test() ---------------------------*/
415 /* This function executes a throughput measurement process and waits for *
416 * that process to finish. When finished, it reads the result from a *
417 * file and returns that result to the caller. The file is then deleted.*
418 * If sched_tc6 is called, then the second time is also read from the *
419 * results file and returned to the caller. *
420 *-----------------------------------------------------------------------*/
measure_test(name,param1,param2,param3,t2)421 float measure_test(name, param1, param2, param3, t2)
422 char *name, /* filename of testcase to run */
423 *param1, /* user flag: 0=user, 1=real time */
424 *param2, /* priority to run the throughput test at */
425 *param3; /* if sched_tc6: fork flag, 0=false, 1=true */
426 float *t2; /* if sched_tc6: second time returned from testcase */
427 {
428 char temp[PATH_MAX], /* holds pathname and returned floating number */
429 t2asc[50]; /* holds second returned floating number */
430 int saved_pid; /* process id of forked process */
431 FILE *datafile; /* file pointer for temporary file */
432
433 /*
434 * Create the path name to be passed to the start_testcase() function
435 */
436 sprintf(temp, "./%s", name);
437
438 /*
439 * Send all the parameters, and start the testcase
440 */
441 saved_pid = start_testcase(temp, name, param1,
442 "-lsch.measure", param2, param3);
443
444 /*
445 * Wait for the testcase to finish
446 */
447 if (debug)
448 printf("waiting on child %d\n", saved_pid);
449 while (wait(NULL) != saved_pid) ;
450
451 /*
452 * Open the temporary file to get the returned number of seconds
453 */
454
455 if ((datafile = fopen("sch.measure", "r")) == NULL) {
456 sys_error("cannot open sch.measure", __FILE__, __LINE__);
457 }
458
459 /*
460 * Read the number of seconds
461 */
462 fgets(temp, 50, datafile);
463 /*added by mpt
464 printf("sched+driver: measure_test: number of seconds=%s\n",temp)
465 *********** */
466
467 /*
468 * If this is sched_tc6, then there is another number we must return
469 */
470
471 if (strcmp(name, "sched_tc6") == 0) {
472 fgets(t2asc, 50, datafile);
473 *t2 = atof(t2asc);
474 }
475
476 /*
477 * Close the temporary file
478 */
479 if (fclose(datafile) != 0) {
480 exit(-1);
481 }
482
483 /*
484 * Now try to remove the temporary file
485 */
486 /*added by MPT
487 printf("measure_test: REMOVING sch.measure\n");
488 fflush(stdout);
489 if (system ("rm sch.measure") < 0)
490 sys_error ("system failed", __FILE__, __LINE__);
491 */
492 return (atof(temp));
493 }
494
495 /*------------------------- display_line() ------------------------------*/
496 /* This procedure displays a line of output given the results of a *
497 * throughput test. It displays the testcase name, the current priority *
498 * level, the user/real time flag, and the elapsed time in seconds, as *
499 * well as the percent change between the current and previous times. *
500 * It then updates the previous elapsed time to be the current one. *
501 *-----------------------------------------------------------------------*/
display_line(char * tcname,int pri,int f,float et,float * pet,int ff)502 void display_line(char *tcname, int pri, int f, float et, float *pet, int ff)
503 {
504 static int display_header = 0;
505 float pc; /* holds percent change */
506
507 /*
508 * Print header every eight lines...
509 */
510 if (display_header-- == 0) {
511 printf("\n Test Processes "
512 " Time Notes\n"
513 "--------- --------------------------- "
514 "--------------- -------\n"
515 "name long short priority mode "
516 "elapsed %%%%delta\n\n");
517 display_header = 6;
518 }
519
520 /*
521 * Calculate the percent change in time
522 */
523 pc = (*pet == 0.0) ? 0.0 : 100.0 * ((et - *pet) / *pet) + 0.05;
524
525 printf("%-12s %2d %2d %2d %4s %06.4f %+06.4f %s\n",
526 tcname, long_running, short_running, pri,
527 (f == 0) ? "user" : "real", et, pc, (ff) ? "forked child" : " ");
528
529 fflush(stdout);
530
531 *pet = et;
532 }
533
534 /*------------------------- perform_throughput_tests() ------------------*/
535 /* This procedure is called each time throughput tests are to be *
536 * performed. This procedure executes each of the throughput tests, and *
537 * records the results of each to the . *
538 *-----------------------------------------------------------------------*/
perform_throughput_tests(int current_priority)539 void perform_throughput_tests(int current_priority)
540 {
541 float esecs, /* elapsed seconds returned from each testcase */
542 esecs2, /* elapsed seconds (second part) for sched_tc6 */
543 pc; /* percent change for sched_tc6 */
544 char pristr[10]; /* holds ascii value of priority as parameter */
545
546 sprintf(pristr, "-p%d", current_priority);
547
548 #if defined(_IA64) && !defined(__64BIT__)
549 esecs =
550 measure_test("sched_tc4.32", "-tvariable", pristr, NULL, &esecs2);
551 display_line("sched_tc4.32", current_priority, 0, esecs, &e4user, 2);
552 esecs = measure_test("sched_tc4.32", "-tfixed", pristr, NULL, &esecs2);
553 display_line("sched_tc4.32", current_priority, 1, esecs, &e4real, 2);
554 esecs =
555 measure_test("sched_tc5.32", "-tvariable", pristr, NULL, &esecs2);
556 display_line("sched_tc5.32", current_priority, 0, esecs, &e5user, 2);
557 esecs = measure_test("sched_tc5.32", "-tfixed", pristr, NULL, &esecs2);
558 display_line("sched_tc5.32", current_priority, 1, esecs, &e5real, 2);
559 esecs =
560 measure_test("sched_tc6.32", "-tvariable", pristr, " -d ", &esecs2);
561 display_line("sched_tc6.32", current_priority, 0, esecs, &e6user0, 0);
562 esecs =
563 measure_test("sched_tc6.32", "-tfixed", pristr, " -d ", &esecs2);
564 display_line("sched_tc6.32", current_priority, 1, esecs, &e6real0, 0);
565 esecs =
566 measure_test("sched_tc6.32", "-tvariable", pristr, " -df ",
567 &esecs2);
568 display_line("sched_tc6.32", current_priority, 0, esecs, &e6user1, 1);
569 #else
570 esecs = measure_test("sched_tc4", "-tvariable", pristr, NULL, &esecs2);
571 display_line("sched_tc4", current_priority, 0, esecs, &e4user, 2);
572 esecs = measure_test("sched_tc4", "-tfixed", pristr, NULL, &esecs2);
573 display_line("sched_tc4", current_priority, 1, esecs, &e4real, 2);
574 esecs = measure_test("sched_tc5", "-tvariable", pristr, NULL, &esecs2);
575 display_line("sched_tc5", current_priority, 0, esecs, &e5user, 2);
576 esecs = measure_test("sched_tc5", "-tfixed", pristr, NULL, &esecs2);
577 display_line("sched_tc5", current_priority, 1, esecs, &e5real, 2);
578 esecs =
579 measure_test("sched_tc6", "-tvariable", pristr, " -d ", &esecs2);
580 display_line("sched_tc6", current_priority, 0, esecs, &e6user0, 0);
581 esecs = measure_test("sched_tc6", "-tfixed", pristr, " -d ", &esecs2);
582 display_line("sched_tc6", current_priority, 1, esecs, &e6real0, 0);
583 esecs =
584 measure_test("sched_tc6", "-tvariable", pristr, " -df ", &esecs2);
585 display_line("sched_tc6", current_priority, 0, esecs, &e6user1, 1);
586 #endif
587
588 /*
589 * Manually build the display line for the second part of sched_tc6
590 */
591
592 /*
593 * Calculate the percent change in time
594 */
595 pc = (e6child ==
596 0.0) ? 0.0 : 100 * ((esecs2 - e6child) / e6child) + 0.05;
597 printf("%-12s forked child %4s %06.4f %+06.4f\n",
598 "sched_tc6", "real", esecs2, pc);
599 e6child = esecs2;
600 }
601
602 /*------------------------ start_long_term_testcases() ------------------*/
603 /* This procedure takes the number of long-term process slots available, *
604 * and executes the long term testcases. *
605 *-----------------------------------------------------------------------*/
start_long_term_testcases(long_term_slot_total,execution_time)606 void start_long_term_testcases(long_term_slot_total, execution_time)
607 int long_term_slot_total; /* total number of long-term slots */
608 char *execution_time; /* runtime hours to pass to each testcase */
609 {
610 int i;
611
612 /*
613 * Now use up the long_term_slot_total by starting testcases call
614 * half with real-time flag '1' set, other half user flag '0'
615 */
616 if (debug)
617 printf("long-term slots available: %d\n",
618 long_term_slot_total);
619
620 for (i = 0; i < (long_term_slot_total / 4); i++) {
621 #if defined(_IA64) && !defined(__64BIT__)
622 start_testcase("./sched_tc0.32", "sched_tc0 -t", execution_time,
623 " -p1", NULL, NULL);
624 start_testcase("./sched_tc2.32", "sched_tc2", execution_time,
625 "1", NULL, NULL);
626 start_testcase("./sched_tc0.32", "sched_tc0 -t", execution_time,
627 " -p0", NULL, NULL);
628 start_testcase("./sched_tc2.32", "sched_tc2", execution_time,
629 "0", NULL, NULL);
630 #else
631 start_testcase("./sched_tc0", "sched_tc0 -t", execution_time,
632 " -p1", NULL, NULL);
633 start_testcase("./sched_tc2", "sched_tc2", execution_time, "1",
634 NULL, NULL);
635 start_testcase("./sched_tc0", "sched_tc0 -t", execution_time,
636 " -p0", NULL, NULL);
637 start_testcase("./sched_tc2", "sched_tc2", execution_time, "0",
638 NULL, NULL);
639 #endif
640 }
641 }
642
643 /*---------------------------------------------------------------------+
644 | start_short_term_testcases () |
645 | ==================================================================== |
646 | |
647 | Function: Starts short term testcases (one for each process slot) |
648 | |
649 +---------------------------------------------------------------------*/
start_short_term_testcases(int short_term_slot_total,double stress_percent,int pri)650 void start_short_term_testcases(int short_term_slot_total,
651 double stress_percent, int pri)
652 {
653 int i;
654 int short_term_slots; /* number of slots to use */
655
656 /*
657 * Set up the short_term_slot_total by starting testcases call
658 * half with real-time flag '1' set, other half user flag '0'
659 */
660 if (available_user_process_slots() < short_term_slot_total)
661 short_term_slots =
662 available_user_process_slots() * stress_percent / 2;
663 else
664 short_term_slots = short_term_slot_total;
665
666 printf("\n<< Starting %d short-term testcases>> \n\n",
667 short_term_slots);
668 if (debug)
669 printf("short-term slots available: %d\n", short_term_slots);
670
671 for (i = 0; i < (short_term_slots / 4); i++) {
672 #if defined(_IA64) && !defined(__64BIT__)
673 start_testcase("./sched_tc1.32", "sched_tc1", "1", NULL, NULL,
674 NULL);
675 start_testcase("./sched_tc3.32", "sched_tc3", "1", NULL, NULL,
676 NULL);
677 start_testcase("./sched_tc1.32", "sched_tc1", "0", NULL, NULL,
678 NULL);
679 start_testcase("./sched_tc3.32", "sched_tc3", "0", NULL, NULL,
680 NULL);
681 #else
682 start_testcase("./sched_tc1", "sched_tc1", "1", NULL, NULL,
683 NULL);
684 start_testcase("./sched_tc3", "sched_tc3", "1", NULL, NULL,
685 NULL);
686 start_testcase("./sched_tc1", "sched_tc1", "0", NULL, NULL,
687 NULL);
688 start_testcase("./sched_tc3", "sched_tc3", "0", NULL, NULL,
689 NULL);
690 #endif
691 #if 0
692 perform_throughput_tests(pri);
693 #endif
694 }
695 }
696
697 /*------------------------ kill_short_term_testcases() ------------------*/
698 /* This procedure goes through the process id table, and sends each *
699 * process id number found in the table a signal in order to terminate *
700 * it. The signal sent is SIGUSR1. It also re-initializes the table. *
701 *-----------------------------------------------------------------------*/
kill_short_term_testcases()702 void kill_short_term_testcases()
703 {
704 int i; /* loop counter to step through the list of process id's */
705
706 /*
707 * Loop through the array of process id's one at a time, and
708 * attempt to kill each one. If kill fails, report error and
709 * continue.
710 */
711 if (debug)
712 printf("killing short-term processes...\n");
713 for (i = 0; i < numprocs; i++) {
714 if (debug)
715 printf("killing process [%d]\n", procs[i]);
716 kill(procs[i], SIGUSR1);
717 }
718
719 /*
720 * Adjust the number of short_term_testcases
721 */
722 short_running -= numprocs;
723
724 /*
725 * Clear the table by setting number of entries to zero
726 */
727 numprocs = 0;
728 }
729
730 /*----------------------------- finishup() ------------------------------*/
731 /* This procedure closing information to the about ending *
732 * times, elapsed times, etc. This procedure then closes the file*
733 *-----------------------------------------------------------------------*/
finishup(start_time)734 void finishup(start_time)
735 long start_time; /* starting time to calculate elapsed time */
736 {
737 long end_time; /* time when program finished */
738
739 /*
740 * Get the end time and calculate elapsed time; write all this out
741 */
742 end_time = time(NULL);
743
744 printf("\nend time = %s\n", ctime(&end_time));
745
746 printf("elapsed time = %4.2f hours\n",
747 ((end_time - start_time) / 3600.0));
748 }
749
750 /*---------------------------------------------------------------------+
751 | parse_args () |
752 | ==================================================================== |
753 | |
754 | Function: Parse the command line arguments & initialize global |
755 | variables. |
756 | |
757 | Updates: (command line options) |
758 | |
759 | [-s] size: shared memory segment size |
760 | |
761 +---------------------------------------------------------------------*/
parse_args(int argc,char ** argv)762 void parse_args(int argc, char **argv)
763 {
764 int opt;
765 int sflg = 0, pflg = 0, tflg = 0;
766 int errflag = 0;
767 char *program_name = *argv;
768 extern char *optarg; /* Command line option */
769
770 /*
771 * Parse command line options.
772 */
773 while ((opt = getopt(argc, argv, "vs:p:t:l:d")) != EOF) {
774 switch (opt) {
775 case 's': /* stress percentage */
776 sflg++;
777 stress_percent = atof(optarg);
778 break;
779 case 'p': /* process slots */
780 pflg++;
781 process_slots = atof(optarg);
782 break;
783 case 't': /* time (hours) */
784 tflg++;
785 execution_time = atof(optarg);
786 break;
787 case 'd': /* Enable debugging messages */
788 debug++;
789 break;
790 case 'v': /* Enable verbose mode=debug mode */
791 debug++;
792 break;
793 default:
794 errflag++;
795 break;
796 }
797 }
798
799 /*
800 * Check percentage, execution time and process slots...
801 */
802 if (sflg) {
803 if (stress_percent < 0.0 || stress_percent > 1.0)
804 errflag++;
805 }
806 if (pflg) {
807 if (process_slots < 0 || process_slots > MAXPROCS)
808 errflag++;
809 }
810 if (tflg) {
811 if (execution_time < 0.0 || execution_time > 100.0)
812 errflag++;
813 }
814 if (debug)
815 printf("\n(debugging messages enabled)\n\n");
816 if (errflag) {
817 fprintf(stderr, USAGE, program_name);
818 exit(2);
819 }
820 }
821