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