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 +---------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 +---------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 *-----------------------------------------------------------------------*/ 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 +---------------------------------------------------------------------*/ 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