sched_driver.c revision ec6edca7aa42b6affd989ef91b5897f96795e40f
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <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 */ 119int 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 */ 123float 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 */ 131double stress_percent = DEFAULT_STRESS_PERCENTAGE; 132double execution_time = DEFAULT_TIME; 133int process_slots = DEFAULT_PROCESS_SLOTS; 134int debug = 0; 135 136/* 137 * Function prototypes 138 */ 139void startup (long); 140int start_testcase (char *, char *, char *, char *, char *, char *); 141int process_slots_in_use (); 142int available_user_process_slots (); 143float measure_test (char *, char *, char *, char *, float *); 144void display_line (char *, int, int, float, float *, int); 145void perform_throughput_tests (int); 146void start_long_term_testcases (int, char *); 147void kill_short_term_testcases (); 148void start_short_term_testcases (int, double, int); 149void finishup (long); 150void parse_args (int, char **); 151 152/*---------------------------------------------------------------------+ 153| main () | 154| ==================================================================== | 155| | 156| Function: Main program | 157| | 158+---------------------------------------------------------------------*/ 159int 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 ((long *) 0); 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", available_user_process_slots ()); 190 printf ("workslots available: %d\n", workslots); 191 printf ("stress_percent: %f\n", stress_percent); 192 printf ("run-hours: %f (hrs)\n", execution_time); 193 printf ("runseconds: %ld (sec)\n", runseconds); 194 } 195 196 /* 197 * Run the first set of tests with an average priority 198 */ 199 perform_throughput_tests ( (MAX_PRI + MIN_PRI) / 2); 200 fflush (stdout); 201 202 /* 203 * Start the long-term testcases running 204 */ 205 start_long_term_testcases (long_term_slot_total, argv[2]); 206 short_term_slot_total = workslots / 2; 207 fflush (stdout); 208 209 /* 210 * Loop while there is still time 211 */ 212 current_priority=MAX_PRI; 213 while ((time(0) - start_time) < runseconds) { 214 215 if (debug) printf ("current priority: %d\n", current_priority); 216 if (debug) printf ("starting short term tests\n"); 217 218 start_short_term_testcases (short_term_slot_total, 219 stress_percent, current_priority); 220 fflush (stdout); 221 222 perform_throughput_tests (current_priority); 223 fflush (stdout); 224 225 if (debug) printf ("killing short term tests\n"); 226 227 kill_short_term_testcases (); 228 fflush (stdout); 229 230 if (current_priority + PRIINC > MIN_PRI) 231 current_priority = MAX_PRI; 232 else 233 current_priority += PRIINC; 234 } 235 236 /* 237 * Exit with success... 238 */ 239 finishup (start_time); 240 printf ("\nsuccessful!\n"); 241 fflush (stdout); 242 return (0); 243} 244 245/*------------------------------ startup() ------------------------------*/ 246/* This procedure opens the , and then outputs some starting * 247 * information to the screen and . It also initializes the * 248 * process id list and other global variables. * 249 *-----------------------------------------------------------------------*/ 250void startup (long start_time) 251{ 252 char tempbuffer[50]; /* temporary buffer to hold names */ 253 254 /* 255 * Now output some diagnostic information 256 */ 257 printf ("start time = %s\n", ctime (&start_time)); 258 259 gethostname (tempbuffer, 40); 260 printf ("host name = %s\n", tempbuffer); 261 262 printf ("user name = %s\n", getpwuid(geteuid())->pw_name); 263 264 printf ("test duration = %4.2f (hours)\n", execution_time); 265 266 printf ("test stress = %4.2f%%%%\n\n", 100 * stress_percent); 267 268 /* 269 * Initialize the global variables 270 */ 271 numprocs = 0; 272 long_running = 0; 273 short_running = 0; 274 e4user = 0.0; 275 e4real = 0.0; 276 e5user = 0.0; 277 e5real = 0.0; 278 e6user0 = 0.0; 279 e6real0 = 0.0; 280 e6user1 = 0.0; 281 e6child = 0.0; 282} 283 284/*--------------------------- start_testcase() --------------------------*/ 285/* This procedure will run a specified testcase by forking a process, and* 286 * then running the testcase with it. It will also store the process id * 287 * number in the process id table. The process id of the child process * 288 * is returned to the calling program. * 289 * name1 pathname of testcase to run * 290 * name2 filename of testcase to run * 291 * param1 parameters to pass to the testcase * 292 * param2 * 293 * param3 * 294 * param4 if sched_tc6: fork flag: 0=false, 1=true * 295 *-----------------------------------------------------------------------*/ 296 297int start_testcase (char *name1, char *name2, char *param1, char *param2, char *param3, char *param4) 298{ 299 int pid, /* pid of currently running process */ 300 pid_save; /* saved pid of process */ 301 302 /* 303 * Fork a process that will run testcase and save the pid 304 */ 305 if (debug) 306 printf ("test: %s %s p1[%s] p2[%s] p3[%s] p4[%s]\n", 307 name1, name2, param1, param2, param3, param4); 308 309 pid_save = pid = fork(); 310 311 /* 312 * If the pid returned is -1, fork failed. If the pid returned is 313 * 0, then the process running is the child process, and we need 314 * to do an 'execl' to run the testcase. If the pid returned is 315 * anything else, then the parent is running, and we return. 316 */ 317 switch (pid) { 318 case -1 : 319 exit (-1); 320 case 0 : 321 execl (name1, name2, param1, param2, param3, param4, NULL); 322 printf ("ERROR: start_testcase(): execl failed.\n"); 323 exit (-1); 324 default : 325 break; 326 } 327 if (debug) 328 printf ("testcase %s started -- pid is %d\n", name2, pid_save); 329 330 /* 331 * If the process just forked is for a short-term testcase, then 332 * add the process id to the table. 333 */ 334 if (debug) printf ("new process: %s ", name2); 335 if (strstr (name2, "tc1") || strstr (name2, "tc3")) { 336 procs[ numprocs ] = pid_save; 337 numprocs++; 338 short_running++; 339 if (debug) printf ("(%d short term)", short_running); 340 } 341 if (strstr (name2, "tc0") || strstr (name2, "tc2")) { 342 long_running++; 343 if (debug) printf ("(%d long term)", long_running); 344 } 345 if (debug) printf ("\n"); 346 347 return (pid_save); 348} 349 350/*------------------------- process_slots_in_use() ----------------------*/ 351/* This function will return the number of process slots currently in use* 352 * by executing the 'ps' command. * 353 *-----------------------------------------------------------------------*/ 354int process_slots_in_use() 355{ 356 FILE *psfile; /* temporary file to hold output of 'ps' command */ 357 int usedslots; /* holds the number of used process slots */ 358 359 /* 360 * Call the 'ps' command and write the number of process slots to a file 361 */ 362 if (system ("ps -e | wc -l > ps.out") < 0) 363 sys_error ("system failed", __FILE__, __LINE__); 364 365 /* 366 * Open the output file 367 */ 368 if ( (psfile = fopen ("ps.out", "r")) == (FILE *) NULL) { 369 exit (-1); 370 } 371 372 /* 373 * Read the number of process slots in use from the file 374 */ 375 fscanf (psfile, "%d", &usedslots); 376 377 /* 378 * Close the output file 379 */ 380 if (fclose (psfile) == -1) { 381 exit (-1); 382 } 383 384 /* 385 * Remove the output file 386 */ 387 if (system ("/bin/rm ps.out") < 0) 388 sys_error ("system failed", __FILE__, __LINE__); 389 390 return (usedslots - 1); 391} 392 393/*----------------------- available_user_process_slots() ----------------*/ 394/* This function returns the total number of available user process slots* 395 * by subtracting the process slots currently in use from the maximum * 396 * possible process slots. * 397 *-----------------------------------------------------------------------*/ 398int available_user_process_slots () 399{ 400 int num = process_slots_in_use (); 401 402 return ( (process_slots < num) ? process_slots : process_slots - num); 403} 404 405/*---------------------------- measure_test() ---------------------------*/ 406/* This function executes a throughput measurement process and waits for * 407 * that process to finish. When finished, it reads the result from a * 408 * file and returns that result to the caller. The file is then deleted.* 409 * If sched_tc6 is called, then the second time is also read from the * 410 * results file and returned to the caller. * 411 *-----------------------------------------------------------------------*/ 412float measure_test (name, param1, param2, param3, t2) 413char *name, /* filename of testcase to run */ 414 *param1, /* user flag: 0=user, 1=real time */ 415 *param2, /* priority to run the throughput test at */ 416 *param3; /* if sched_tc6: fork flag, 0=false, 1=true */ 417float *t2; /* if sched_tc6: second time returned from testcase */ 418{ 419 char temp[PATH_MAX], /* holds pathname and returned floating number */ 420 t2asc[50]; /* holds second returned floating number */ 421 int saved_pid; /* process id of forked process */ 422 FILE *datafile; /* file pointer for temporary file */ 423 424 /* 425 * Create the path name to be passed to the start_testcase() function 426 */ 427 sprintf (temp, "./%s", name); 428 429 /* 430 * Send all the parameters, and start the testcase 431 */ 432 saved_pid = start_testcase (temp, name, param1, 433 "-lsch.measure", param2, param3); 434 435 /* 436 * Wait for the testcase to finish 437 */ 438 if (debug) printf ("waiting on child %d\n", saved_pid); 439 while (wait((void *) 0) != saved_pid) ; 440 441 /* 442 * Open the temporary file to get the returned number of seconds 443 */ 444 445 if ((datafile = fopen ("sch.measure", "r")) == (FILE *) NULL) { 446 sys_error ("cannot open sch.measure", __FILE__, __LINE__); 447 } 448 449 /* 450 * Read the number of seconds 451 */ 452 fgets (temp, 50, datafile); 453 /*added by mpt 454 printf("sched+driver: measure_test: number of seconds=%s\n",temp) 455 *********** */ 456 457 /* 458 * If this is sched_tc6, then there is another number we must return 459 */ 460 461 if (strcmp (name, "sched_tc6") == 0) { 462 fgets (t2asc, 50, datafile); 463 *t2 = atof (t2asc); 464 } 465 466 /* 467 * Close the temporary file 468 */ 469 if (fclose (datafile) != 0) { 470 exit (-1); 471 } 472 473 /* 474 * Now try to remove the temporary file 475 */ 476 /*added by MPT 477 printf("measure_test: REMOVING sch.measure\n"); 478 fflush(stdout); 479 if (system ("rm sch.measure") < 0) 480 sys_error ("system failed", __FILE__, __LINE__); 481 */ 482 return (atof (temp)); 483} 484 485/*------------------------- display_line() ------------------------------*/ 486/* This procedure displays a line of output given the results of a * 487 * throughput test. It displays the testcase name, the current priority * 488 * level, the user/real time flag, and the elapsed time in seconds, as * 489 * well as the percent change between the current and previous times. * 490 * It then updates the previous elapsed time to be the current one. * 491 *-----------------------------------------------------------------------*/ 492void display_line (char *tcname, int pri, int f, float et, float *pet, int ff) 493{ 494 static int display_header = 0; 495 float pc; /* holds percent change */ 496 497 /* 498 * Print header every eight lines... 499 */ 500 if (display_header-- == 0) { 501 printf ("\n Test Processes " \ 502 " Time Notes\n" \ 503 "--------- --------------------------- " \ 504 "--------------- -------\n" \ 505 "name long short priority mode " \ 506 "elapsed %%%%delta\n\n"); 507 display_header = 6; 508 } 509 510 /* 511 * Calculate the percent change in time 512 */ 513 pc = (*pet == 0.0)? 0.0 : 100.0 * ( (et - *pet) / *pet) + 0.05; 514 515 printf ("%-12s %2d %2d %2d %4s %06.4f %+06.4f %s\n", 516 tcname, long_running, short_running, pri, 517 (f == 0) ? "user" : "real", 518 et, pc, 519 (ff) ? "forked child" : " "); 520 521 fflush (stdout); 522 523 *pet = et; 524} 525 526/*------------------------- perform_throughput_tests() ------------------*/ 527/* This procedure is called each time throughput tests are to be * 528 * performed. This procedure executes each of the throughput tests, and * 529 * records the results of each to the . * 530 *-----------------------------------------------------------------------*/ 531void perform_throughput_tests (int current_priority) 532{ 533 float esecs, /* elapsed seconds returned from each testcase */ 534 esecs2, /* elapsed seconds (second part) for sched_tc6 */ 535 pc; /* percent change for sched_tc6 */ 536 char pristr[10]; /* holds ascii value of priority as parameter */ 537 538 sprintf (pristr, "-p%d", current_priority); 539 540#if defined(_IA64) && !defined(__64BIT__) 541 esecs = measure_test ("sched_tc4.32", "-tvariable", pristr, NULL, &esecs2); 542 display_line ("sched_tc4.32", current_priority, 0, esecs, &e4user, 2); 543 esecs = measure_test ("sched_tc4.32", "-tfixed", pristr, NULL, &esecs2); 544 display_line ("sched_tc4.32", current_priority, 1, esecs, &e4real, 2); 545 esecs = measure_test ("sched_tc5.32", "-tvariable", pristr, NULL, &esecs2); 546 display_line ("sched_tc5.32", current_priority, 0, esecs, &e5user, 2); 547 esecs = measure_test ("sched_tc5.32", "-tfixed", pristr, NULL, &esecs2); 548 display_line ("sched_tc5.32", current_priority, 1, esecs, &e5real, 2); 549 esecs = measure_test ("sched_tc6.32", "-tvariable", pristr, " -d ", &esecs2); 550 display_line ("sched_tc6.32", current_priority, 0, esecs, &e6user0, 0); 551 esecs = measure_test ("sched_tc6.32", "-tfixed", pristr, " -d ", &esecs2); 552 display_line ("sched_tc6.32", current_priority, 1, esecs, &e6real0, 0); 553 esecs = measure_test ("sched_tc6.32", "-tvariable", pristr, " -df ", &esecs2); 554 display_line ("sched_tc6.32", current_priority, 0, esecs, &e6user1, 1); 555#else 556 esecs = measure_test ("sched_tc4", "-tvariable", pristr, NULL, &esecs2); 557 display_line ("sched_tc4", current_priority, 0, esecs, &e4user, 2); 558 esecs = measure_test ("sched_tc4", "-tfixed", pristr, NULL, &esecs2); 559 display_line ("sched_tc4", current_priority, 1, esecs, &e4real, 2); 560 esecs = measure_test ("sched_tc5", "-tvariable", pristr, NULL, &esecs2); 561 display_line ("sched_tc5", current_priority, 0, esecs, &e5user, 2); 562 esecs = measure_test ("sched_tc5", "-tfixed", pristr, NULL, &esecs2); 563 display_line ("sched_tc5", current_priority, 1, esecs, &e5real, 2); 564 esecs = measure_test ("sched_tc6", "-tvariable", pristr, " -d ", &esecs2); 565 display_line ("sched_tc6", current_priority, 0, esecs, &e6user0, 0); 566 esecs = measure_test ("sched_tc6", "-tfixed", pristr, " -d ", &esecs2); 567 display_line ("sched_tc6", current_priority, 1, esecs, &e6real0, 0); 568 esecs = measure_test ("sched_tc6", "-tvariable", pristr, " -df ", &esecs2); 569 display_line ("sched_tc6", current_priority, 0, esecs, &e6user1, 1); 570#endif 571 572 /* 573 * Manually build the display line for the second part of sched_tc6 574 */ 575 576 /* 577 * Calculate the percent change in time 578 */ 579 pc = (e6child == 0.0) ? 0.0 : 100 * ((esecs2 - e6child)/e6child) + 0.05; 580 printf ("%-12s forked child %4s %06.4f %+06.4f\n", 581 "sched_tc6", "real", esecs2, pc); 582 e6child = esecs2; 583} 584 585/*------------------------ start_long_term_testcases() ------------------*/ 586/* This procedure takes the number of long-term process slots available, * 587 * and executes the long term testcases. * 588 *-----------------------------------------------------------------------*/ 589void start_long_term_testcases (long_term_slot_total, execution_time) 590int long_term_slot_total; /* total number of long-term slots */ 591char *execution_time; /* runtime hours to pass to each testcase */ 592{ 593 int i; 594 595 /* 596 * Now use up the long_term_slot_total by starting testcases call 597 * half with real-time flag '1' set, other half user flag '0' 598 */ 599 if (debug) 600 printf ("long-term slots available: %d\n", long_term_slot_total); 601 602 for (i = 0; i < (long_term_slot_total/4); i++) { 603#if defined(_IA64) && !defined(__64BIT__) 604 start_testcase ("./sched_tc0.32", "sched_tc0 -t", execution_time, " -p1", NULL, NULL); 605 start_testcase ("./sched_tc2.32", "sched_tc2", execution_time, "1", NULL, NULL); 606 start_testcase ("./sched_tc0.32", "sched_tc0 -t", execution_time, " -p0", NULL, NULL); 607 start_testcase ("./sched_tc2.32", "sched_tc2", execution_time, "0", NULL, NULL); 608#else 609 start_testcase ("./sched_tc0", "sched_tc0 -t", execution_time, " -p1", NULL, NULL); 610 start_testcase ("./sched_tc2", "sched_tc2", execution_time, "1", NULL, NULL); 611 start_testcase ("./sched_tc0", "sched_tc0 -t", execution_time, " -p0", NULL, NULL); 612 start_testcase ("./sched_tc2", "sched_tc2", execution_time, "0", NULL, NULL); 613#endif 614 } 615} 616 617/*---------------------------------------------------------------------+ 618| start_short_term_testcases () | 619| ==================================================================== | 620| | 621| Function: Starts short term testcases (one for each process slot) | 622| | 623+---------------------------------------------------------------------*/ 624void start_short_term_testcases (int short_term_slot_total, double stress_percent, int pri) 625{ 626 int i; 627 int short_term_slots; /* number of slots to use */ 628 629 /* 630 * Set up the short_term_slot_total by starting testcases call 631 * half with real-time flag '1' set, other half user flag '0' 632 */ 633 if (available_user_process_slots() < short_term_slot_total) 634 short_term_slots = available_user_process_slots() * stress_percent / 2; 635 else 636 short_term_slots = short_term_slot_total; 637 638 printf ("\n<< Starting %d short-term testcases>> \n\n", short_term_slots); 639 if (debug) 640 printf ("short-term slots available: %d\n", short_term_slots); 641 642 for (i = 0; i < (short_term_slots/4); i++) { 643#if defined(_IA64) && !defined(__64BIT__) 644 start_testcase ("./sched_tc1.32", "sched_tc1", "1", NULL, NULL, NULL); 645 start_testcase ("./sched_tc3.32", "sched_tc3", "1", NULL, NULL, NULL); 646 start_testcase ("./sched_tc1.32", "sched_tc1", "0", NULL, NULL, NULL); 647 start_testcase ("./sched_tc3.32", "sched_tc3", "0", NULL, NULL, NULL); 648#else 649 start_testcase ("./sched_tc1", "sched_tc1", "1", NULL, NULL, NULL); 650 start_testcase ("./sched_tc3", "sched_tc3", "1", NULL, NULL, NULL); 651 start_testcase ("./sched_tc1", "sched_tc1", "0", NULL, NULL, NULL); 652 start_testcase ("./sched_tc3", "sched_tc3", "0", NULL, NULL, NULL); 653#endif 654#if 0 655 perform_throughput_tests (pri); 656#endif 657 } 658} 659 660/*------------------------ kill_short_term_testcases() ------------------*/ 661/* This procedure goes through the process id table, and sends each * 662 * process id number found in the table a signal in order to terminate * 663 * it. The signal sent is SIGUSR1. It also re-initializes the table. * 664 *-----------------------------------------------------------------------*/ 665void kill_short_term_testcases() 666{ 667 int i; /* loop counter to step through the list of process id's */ 668 669 /* 670 * Loop through the array of process id's one at a time, and 671 * attempt to kill each one. If kill fails, report error and 672 * continue. 673 */ 674 if (debug) 675 printf ("killing short-term processes...\n"); 676 for (i = 0; i < numprocs; i++) { 677 if (debug) printf ("killing process [%d]\n", procs [i]); 678 kill (procs[i], SIGUSR1); 679 } 680 681 /* 682 * Adjust the number of short_term_testcases 683 */ 684 short_running -= numprocs; 685 686 /* 687 * Clear the table by setting number of entries to zero 688 */ 689 numprocs = 0; 690} 691 692/*----------------------------- finishup() ------------------------------*/ 693/* This procedure closing information to the about ending * 694 * times, elapsed times, etc. This procedure then closes the file* 695 *-----------------------------------------------------------------------*/ 696void finishup (start_time) 697long start_time; /* starting time to calculate elapsed time */ 698{ 699 long end_time; /* time when program finished */ 700 701 /* 702 * Get the end time and calculate elapsed time; write all this out 703 */ 704 end_time = time ((long *) 0); 705 706 printf ("\nend time = %s\n", ctime (&end_time)); 707 708 printf ("elapsed time = %4.2f hours\n", 709 ( (end_time - start_time) / 3600.0)); 710} 711 712/*---------------------------------------------------------------------+ 713| parse_args () | 714| ==================================================================== | 715| | 716| Function: Parse the command line arguments & initialize global | 717| variables. | 718| | 719| Updates: (command line options) | 720| | 721| [-s] size: shared memory segment size | 722| | 723+---------------------------------------------------------------------*/ 724void parse_args (int argc, char **argv) 725{ 726 int opt; 727 int sflg = 0, pflg = 0, tflg = 0; 728 int errflag = 0; 729 char *program_name = *argv; 730 extern char *optarg; /* Command line option */ 731 732 /* 733 * Parse command line options. 734 */ 735 while ((opt = getopt(argc, argv, "vs:p:t:l:d")) != EOF) 736 { 737 switch (opt) 738 { 739 case 's': /* stress percentage */ 740 sflg++; 741 stress_percent = atof (optarg); 742 break; 743 case 'p': /* process slots */ 744 pflg++; 745 process_slots = atof (optarg); 746 break; 747 case 't': /* time (hours) */ 748 tflg++; 749 execution_time = atof (optarg); 750 break; 751 case 'd': /* Enable debugging messages */ 752 debug++; 753 break; 754 case 'v': /* Enable verbose mode=debug mode */ 755 debug++; 756 break; 757 default: 758 errflag++; 759 break; 760 } 761 } 762 763 /* 764 * Check percentage, execution time and process slots... 765 */ 766 if (sflg) { 767 if (stress_percent < 0.0 || stress_percent > 1.0) 768 errflag++; 769 } 770 if (pflg) { 771 if (process_slots < 0 || process_slots > MAXPROCS) 772 errflag++; 773 } 774 if (tflg) { 775 if (execution_time < 0.0 || execution_time > 100.0) 776 errflag++; 777 } 778 if (debug) 779 printf ("\n(debugging messages enabled)\n\n"); 780 if (errflag) { 781 fprintf (stderr, USAGE, program_name); 782 exit (2); 783 } 784} 785