blob: 61573d788813b9b7e676ec95efd892c763ca01b3 [file] [log] [blame]
iyermanoj28eaa912002-01-04 20:28:52 +00001/*
iyermanoj28eaa912002-01-04 20:28:52 +00002 * 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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
iyermanoj28eaa912002-01-04 20:28:52 +000017 */
iyermanoj28eaa912002-01-04 20:28:52 +000018/*---------------------------------------------------------------------+
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 |
subrata_modak4bb656a2009-02-26 12:02:09 +000042| |
iyermanoj28eaa912002-01-04 20:28:52 +000043| 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
robbiewda0cc972003-03-28 17:18:51 +000064#include <sys/types.h>
65#include <unistd.h>
Steven Jackson249f4052016-12-13 16:16:00 +000066#include <sys/wait.h>
robbiewda0cc972003-03-28 17:18:51 +000067#include <string.h>
iyermanoj28eaa912002-01-04 20:28:52 +000068#include <stdlib.h>
69#include <signal.h>
robbiew0e1e2a52002-09-04 16:25:53 +000070#include <pwd.h>
robbiew1e6794a2002-09-05 19:15:26 +000071#include <time.h>
subrata_modak8b95b602008-10-23 07:37:40 +000072#include <limits.h>
iyermanoj28eaa912002-01-04 20:28:52 +000073#include "sched.h"
74
75/*
76 * Defines:
subrata_modak4bb656a2009-02-26 12:02:09 +000077 *
iyermanoj28eaa912002-01-04 20:28:52 +000078 * MAXPROCS: maximum number of processes
subrata_modak4bb656a2009-02-26 12:02:09 +000079 *
iyermanoj28eaa912002-01-04 20:28:52 +000080 * PRIINC: priority step value
subrata_modak4bb656a2009-02-26 12:02:09 +000081 *
iyermanoj28eaa912002-01-04 20:28:52 +000082 * MAX_PRI: highest priority to use
subrata_modak4bb656a2009-02-26 12:02:09 +000083 *
iyermanoj28eaa912002-01-04 20:28:52 +000084 * MIN_PRI: lowest priority to use
subrata_modak4bb656a2009-02-26 12:02:09 +000085 *
iyermanoj28eaa912002-01-04 20:28:52 +000086 * DEFAULT_STRESS_PERCENTAGE: stress percentage (process slot multiplier)
subrata_modak4bb656a2009-02-26 12:02:09 +000087 *
iyermanoj28eaa912002-01-04 20:28:52 +000088 * DEFAULT_PROCESS_SLOTS: number of processes test driver will try and create
subrata_modak4bb656a2009-02-26 12:02:09 +000089 *
iyermanoj28eaa912002-01-04 20:28:52 +000090 * DEFAULT_TIME: time (hours) for which this test driver will run
subrata_modak4bb656a2009-02-26 12:02:09 +000091 *
iyermanoj28eaa912002-01-04 20:28:52 +000092 * USAGE: usage statement
93 */
94#define MAXPROCS 100
95#define PRIINC 2
Wanlong Gao354ebb42012-12-07 10:10:04 +080096#define MAX_PRI 55 /* was 50 */
97#define MIN_PRI 75 /* was 64 */
iyermanoj28eaa912002-01-04 20:28:52 +000098#define DEFAULT_STRESS_PERCENTAGE 0.5
99#define DEFAULT_PROCESS_SLOTS 16
100#define DEFAULT_TIME 1.00
robbiew1e6794a2002-09-05 19:15:26 +0000101#define USAGE "Usage: %s [-s n] [-p n] [-t n] [-d] [-v] \n" \
iyermanoj28eaa912002-01-04 20:28:52 +0000102 " -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:
subrata_modak4bb656a2009-02-26 12:02:09 +0000110 *
iyermanoj28eaa912002-01-04 20:28:52 +0000111 * stress_percent: stress percentage
subrata_modak4bb656a2009-02-26 12:02:09 +0000112 *
iyermanoj28eaa912002-01-04 20:28:52 +0000113 * :
subrata_modak4bb656a2009-02-26 12:02:09 +0000114 *
iyermanoj28eaa912002-01-04 20:28:52 +0000115 * execution_time: execution time in hours
subrata_modak4bb656a2009-02-26 12:02:09 +0000116 *
iyermanoj28eaa912002-01-04 20:28:52 +0000117 * debug: (option flag) enables debugging messages
118 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800119int 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;
iyermanoj28eaa912002-01-04 20:28:52 +0000135
iyermanoj28eaa912002-01-04 20:28:52 +0000136/*
137 * Function prototypes
138 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139void 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 **);
iyermanoj28eaa912002-01-04 20:28:52 +0000151
iyermanoj28eaa912002-01-04 20:28:52 +0000152/*---------------------------------------------------------------------+
153| main () |
154| ==================================================================== |
155| |
156| Function: Main program |
157| |
158+---------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800159int main(int argc, char **argv)
iyermanoj28eaa912002-01-04 20:28:52 +0000160{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800161 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 */
iyermanoj28eaa912002-01-04 20:28:52 +0000167
168 /*
169 * Parse command line arguments & printer program header...
170 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800171 parse_args(argc, argv);
172 printf("Scheduler Testsuite Program\n\n");
173 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000174
175 /*
176 * Calculate number of seconds to run, then print out start info
177 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178 runseconds = (long)(execution_time * 60.0 * 60.0);
Cyril Hrubis4e2bab82014-09-24 16:34:35 +0200179 start_time = time(NULL);
iyermanoj28eaa912002-01-04 20:28:52 +0000180
Wanlong Gao354ebb42012-12-07 10:10:04 +0800181 startup(start_time);
iyermanoj28eaa912002-01-04 20:28:52 +0000182
subrata_modak4bb656a2009-02-26 12:02:09 +0000183 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000184 * 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) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800189 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000195 }
196
subrata_modak4bb656a2009-02-26 12:02:09 +0000197 /*
198 * Run the first set of tests with an average priority
iyermanoj28eaa912002-01-04 20:28:52 +0000199 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800200 perform_throughput_tests((MAX_PRI + MIN_PRI) / 2);
201 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000202
subrata_modak4bb656a2009-02-26 12:02:09 +0000203 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000204 * Start the long-term testcases running
205 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800206 start_long_term_testcases(long_term_slot_total, argv[2]);
iyermanoj28eaa912002-01-04 20:28:52 +0000207 short_term_slot_total = workslots / 2;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800208 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000209
subrata_modak4bb656a2009-02-26 12:02:09 +0000210 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000211 * Loop while there is still time
212 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800213 current_priority = MAX_PRI;
subrata_modak4bb656a2009-02-26 12:02:09 +0000214 while ((time(0) - start_time) < runseconds) {
iyermanoj28eaa912002-01-04 20:28:52 +0000215
Wanlong Gao354ebb42012-12-07 10:10:04 +0800216 if (debug)
217 printf("current priority: %d\n", current_priority);
218 if (debug)
219 printf("starting short term tests\n");
iyermanoj28eaa912002-01-04 20:28:52 +0000220
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 start_short_term_testcases(short_term_slot_total,
222 stress_percent, current_priority);
223 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000224
Wanlong Gao354ebb42012-12-07 10:10:04 +0800225 perform_throughput_tests(current_priority);
226 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000227
Wanlong Gao354ebb42012-12-07 10:10:04 +0800228 if (debug)
229 printf("killing short term tests\n");
iyermanoj28eaa912002-01-04 20:28:52 +0000230
Wanlong Gao354ebb42012-12-07 10:10:04 +0800231 kill_short_term_testcases();
232 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000233
234 if (current_priority + PRIINC > MIN_PRI)
235 current_priority = MAX_PRI;
236 else
237 current_priority += PRIINC;
238 }
239
subrata_modak4bb656a2009-02-26 12:02:09 +0000240 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000241 * Exit with success...
242 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800243 finishup(start_time);
244 printf("\nsuccessful!\n");
245 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000246 return (0);
247}
248
iyermanoj28eaa912002-01-04 20:28:52 +0000249/*------------------------------ 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 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800254void startup(long start_time)
iyermanoj28eaa912002-01-04 20:28:52 +0000255{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256 char tempbuffer[50]; /* temporary buffer to hold names */
iyermanoj28eaa912002-01-04 20:28:52 +0000257
subrata_modak4bb656a2009-02-26 12:02:09 +0000258 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000259 * Now output some diagnostic information
260 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800261 printf("start time = %s\n", ctime(&start_time));
iyermanoj28eaa912002-01-04 20:28:52 +0000262
Wanlong Gao354ebb42012-12-07 10:10:04 +0800263 gethostname(tempbuffer, 40);
264 printf("host name = %s\n", tempbuffer);
iyermanoj28eaa912002-01-04 20:28:52 +0000265
Wanlong Gao354ebb42012-12-07 10:10:04 +0800266 printf("user name = %s\n", getpwuid(geteuid())->pw_name);
iyermanoj28eaa912002-01-04 20:28:52 +0000267
Wanlong Gao354ebb42012-12-07 10:10:04 +0800268 printf("test duration = %4.2f (hours)\n", execution_time);
iyermanoj28eaa912002-01-04 20:28:52 +0000269
Wanlong Gao354ebb42012-12-07 10:10:04 +0800270 printf("test stress = %4.2f%%%%\n\n", 100 * stress_percent);
iyermanoj28eaa912002-01-04 20:28:52 +0000271
subrata_modak4bb656a2009-02-26 12:02:09 +0000272 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000273 * 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
iyermanoj28eaa912002-01-04 20:28:52 +0000288/*--------------------------- 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
Wanlong Gao354ebb42012-12-07 10:10:04 +0800301int start_testcase(char *name1, char *name2, char *param1, char *param2,
302 char *param3, char *param4)
iyermanoj28eaa912002-01-04 20:28:52 +0000303{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800304 int pid, /* pid of currently running process */
305 pid_save; /* saved pid of process */
iyermanoj28eaa912002-01-04 20:28:52 +0000306
subrata_modak4bb656a2009-02-26 12:02:09 +0000307 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000308 * Fork a process that will run testcase and save the pid
309 */
subrata_modak4bb656a2009-02-26 12:02:09 +0000310 if (debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800311 printf("test: %s %s p1[%s] p2[%s] p3[%s] p4[%s]\n",
312 name1, name2, param1, param2, param3, param4);
iyermanoj28eaa912002-01-04 20:28:52 +0000313
314 pid_save = pid = fork();
315
subrata_modak4bb656a2009-02-26 12:02:09 +0000316 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000317 * 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) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800323 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;
iyermanoj28eaa912002-01-04 20:28:52 +0000331 }
332 if (debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800333 printf("testcase %s started -- pid is %d\n", name2, pid_save);
iyermanoj28eaa912002-01-04 20:28:52 +0000334
subrata_modak4bb656a2009-02-26 12:02:09 +0000335 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000336 * If the process just forked is for a short-term testcase, then
337 * add the process id to the table.
338 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800339 if (debug)
340 printf("new process: %s ", name2);
341 if (strstr(name2, "tc1") || strstr(name2, "tc3")) {
342 procs[numprocs] = pid_save;
iyermanoj28eaa912002-01-04 20:28:52 +0000343 numprocs++;
344 short_running++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800345 if (debug)
346 printf("(%d short term)", short_running);
iyermanoj28eaa912002-01-04 20:28:52 +0000347 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800348 if (strstr(name2, "tc0") || strstr(name2, "tc2")) {
iyermanoj28eaa912002-01-04 20:28:52 +0000349 long_running++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800350 if (debug)
351 printf("(%d long term)", long_running);
iyermanoj28eaa912002-01-04 20:28:52 +0000352 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800353 if (debug)
354 printf("\n");
iyermanoj28eaa912002-01-04 20:28:52 +0000355
356 return (pid_save);
357}
358
iyermanoj28eaa912002-01-04 20:28:52 +0000359/*------------------------- process_slots_in_use() ----------------------*/
360/* This function will return the number of process slots currently in use*
361 * by executing the 'ps' command. *
362 *-----------------------------------------------------------------------*/
363int process_slots_in_use()
364{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800365 FILE *psfile; /* temporary file to hold output of 'ps' command */
366 int usedslots; /* holds the number of used process slots */
iyermanoj28eaa912002-01-04 20:28:52 +0000367
subrata_modak4bb656a2009-02-26 12:02:09 +0000368 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000369 * Call the 'ps' command and write the number of process slots to a file
370 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800371 if (system("ps -e | wc -l > ps.out") < 0)
372 sys_error("system failed", __FILE__, __LINE__);
iyermanoj28eaa912002-01-04 20:28:52 +0000373
subrata_modak4bb656a2009-02-26 12:02:09 +0000374 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000375 * Open the output file
376 */
Cyril Hrubiscf0d6262014-09-23 14:03:31 +0200377 if ((psfile = fopen("ps.out", "r")) == NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800378 exit(-1);
iyermanoj28eaa912002-01-04 20:28:52 +0000379 }
380
subrata_modak4bb656a2009-02-26 12:02:09 +0000381 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000382 * Read the number of process slots in use from the file
383 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800384 fscanf(psfile, "%d", &usedslots);
iyermanoj28eaa912002-01-04 20:28:52 +0000385
subrata_modak4bb656a2009-02-26 12:02:09 +0000386 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000387 * Close the output file
388 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800389 if (fclose(psfile) == -1) {
390 exit(-1);
iyermanoj28eaa912002-01-04 20:28:52 +0000391 }
392
subrata_modak4bb656a2009-02-26 12:02:09 +0000393 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000394 * Remove the output file
395 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800396 if (system("/bin/rm ps.out") < 0)
397 sys_error("system failed", __FILE__, __LINE__);
iyermanoj28eaa912002-01-04 20:28:52 +0000398
399 return (usedslots - 1);
400}
401
iyermanoj28eaa912002-01-04 20:28:52 +0000402/*----------------------- 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 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800407int available_user_process_slots()
iyermanoj28eaa912002-01-04 20:28:52 +0000408{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800409 int num = process_slots_in_use();
iyermanoj28eaa912002-01-04 20:28:52 +0000410
Wanlong Gao354ebb42012-12-07 10:10:04 +0800411 return ((process_slots < num) ? process_slots : process_slots - num);
iyermanoj28eaa912002-01-04 20:28:52 +0000412}
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 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800421float measure_test(name, param1, param2, param3, t2)
422char *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 */
426float *t2; /* if sched_tc6: second time returned from testcase */
iyermanoj28eaa912002-01-04 20:28:52 +0000427{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800428 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 */
iyermanoj28eaa912002-01-04 20:28:52 +0000432
subrata_modak4bb656a2009-02-26 12:02:09 +0000433 /*
434 * Create the path name to be passed to the start_testcase() function
iyermanoj28eaa912002-01-04 20:28:52 +0000435 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800436 sprintf(temp, "./%s", name);
iyermanoj28eaa912002-01-04 20:28:52 +0000437
subrata_modak4bb656a2009-02-26 12:02:09 +0000438 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000439 * Send all the parameters, and start the testcase
440 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800441 saved_pid = start_testcase(temp, name, param1,
442 "-lsch.measure", param2, param3);
iyermanoj28eaa912002-01-04 20:28:52 +0000443
subrata_modak4bb656a2009-02-26 12:02:09 +0000444 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000445 * Wait for the testcase to finish
446 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800447 if (debug)
448 printf("waiting on child %d\n", saved_pid);
Cyril Hrubis4e2bab82014-09-24 16:34:35 +0200449 while (wait(NULL) != saved_pid) ;
iyermanoj28eaa912002-01-04 20:28:52 +0000450
subrata_modak4bb656a2009-02-26 12:02:09 +0000451 /*
452 * Open the temporary file to get the returned number of seconds
iyermanoj28eaa912002-01-04 20:28:52 +0000453 */
454
Cyril Hrubiscf0d6262014-09-23 14:03:31 +0200455 if ((datafile = fopen("sch.measure", "r")) == NULL) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800456 sys_error("cannot open sch.measure", __FILE__, __LINE__);
iyermanoj28eaa912002-01-04 20:28:52 +0000457 }
458
subrata_modak4bb656a2009-02-26 12:02:09 +0000459 /*
460 * Read the number of seconds
iyermanoj28eaa912002-01-04 20:28:52 +0000461 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800462 fgets(temp, 50, datafile);
iyermanoj28eaa912002-01-04 20:28:52 +0000463 /*added by mpt
Wanlong Gao354ebb42012-12-07 10:10:04 +0800464 printf("sched+driver: measure_test: number of seconds=%s\n",temp)
465 *********** */
iyermanoj28eaa912002-01-04 20:28:52 +0000466
subrata_modak4bb656a2009-02-26 12:02:09 +0000467 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000468 * If this is sched_tc6, then there is another number we must return
469 */
470
Wanlong Gao354ebb42012-12-07 10:10:04 +0800471 if (strcmp(name, "sched_tc6") == 0) {
472 fgets(t2asc, 50, datafile);
473 *t2 = atof(t2asc);
iyermanoj28eaa912002-01-04 20:28:52 +0000474 }
475
subrata_modak4bb656a2009-02-26 12:02:09 +0000476 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000477 * Close the temporary file
478 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800479 if (fclose(datafile) != 0) {
480 exit(-1);
iyermanoj28eaa912002-01-04 20:28:52 +0000481 }
482
subrata_modak4bb656a2009-02-26 12:02:09 +0000483 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000484 * Now try to remove the temporary file
485 */
486 /*added by MPT
Wanlong Gao354ebb42012-12-07 10:10:04 +0800487 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));
iyermanoj28eaa912002-01-04 20:28:52 +0000493}
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 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800502void display_line(char *tcname, int pri, int f, float et, float *pet, int ff)
iyermanoj28eaa912002-01-04 20:28:52 +0000503{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800504 static int display_header = 0;
505 float pc; /* holds percent change */
iyermanoj28eaa912002-01-04 20:28:52 +0000506
subrata_modak4bb656a2009-02-26 12:02:09 +0000507 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000508 * Print header every eight lines...
509 */
510 if (display_header-- == 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800511 printf("\n Test Processes "
512 " Time Notes\n"
513 "--------- --------------------------- "
514 "--------------- -------\n"
515 "name long short priority mode "
516 "elapsed %%%%delta\n\n");
iyermanoj28eaa912002-01-04 20:28:52 +0000517 display_header = 6;
518 }
519
subrata_modak4bb656a2009-02-26 12:02:09 +0000520 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000521 * Calculate the percent change in time
522 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800523 pc = (*pet == 0.0) ? 0.0 : 100.0 * ((et - *pet) / *pet) + 0.05;
iyermanoj28eaa912002-01-04 20:28:52 +0000524
Wanlong Gao354ebb42012-12-07 10:10:04 +0800525 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" : " ");
iyermanoj28eaa912002-01-04 20:28:52 +0000528
Wanlong Gao354ebb42012-12-07 10:10:04 +0800529 fflush(stdout);
iyermanoj28eaa912002-01-04 20:28:52 +0000530
531 *pet = et;
532}
533
iyermanoj28eaa912002-01-04 20:28:52 +0000534/*------------------------- 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 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800539void perform_throughput_tests(int current_priority)
iyermanoj28eaa912002-01-04 20:28:52 +0000540{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800541 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 */
iyermanoj28eaa912002-01-04 20:28:52 +0000545
Wanlong Gao354ebb42012-12-07 10:10:04 +0800546 sprintf(pristr, "-p%d", current_priority);
iyermanoj28eaa912002-01-04 20:28:52 +0000547
548#if defined(_IA64) && !defined(__64BIT__)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800549 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000569#else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800570 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000586#endif
587
subrata_modak4bb656a2009-02-26 12:02:09 +0000588 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000589 * Manually build the display line for the second part of sched_tc6
590 */
591
subrata_modak4bb656a2009-02-26 12:02:09 +0000592 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000593 * Calculate the percent change in time
594 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800595 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000599 e6child = esecs2;
600}
601
iyermanoj28eaa912002-01-04 20:28:52 +0000602/*------------------------ start_long_term_testcases() ------------------*/
603/* This procedure takes the number of long-term process slots available, *
604 * and executes the long term testcases. *
605 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800606void start_long_term_testcases(long_term_slot_total, execution_time)
607int long_term_slot_total; /* total number of long-term slots */
608char *execution_time; /* runtime hours to pass to each testcase */
iyermanoj28eaa912002-01-04 20:28:52 +0000609{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800610 int i;
iyermanoj28eaa912002-01-04 20:28:52 +0000611
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)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800617 printf("long-term slots available: %d\n",
618 long_term_slot_total);
iyermanoj28eaa912002-01-04 20:28:52 +0000619
Wanlong Gao354ebb42012-12-07 10:10:04 +0800620 for (i = 0; i < (long_term_slot_total / 4); i++) {
iyermanoj28eaa912002-01-04 20:28:52 +0000621#if defined(_IA64) && !defined(__64BIT__)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800622 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000630#else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800631 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000639#endif
640 }
641}
642
iyermanoj28eaa912002-01-04 20:28:52 +0000643/*---------------------------------------------------------------------+
644| start_short_term_testcases () |
645| ==================================================================== |
646| |
647| Function: Starts short term testcases (one for each process slot) |
648| |
649+---------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800650void start_short_term_testcases(int short_term_slot_total,
651 double stress_percent, int pri)
iyermanoj28eaa912002-01-04 20:28:52 +0000652{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800653 int i;
654 int short_term_slots; /* number of slots to use */
iyermanoj28eaa912002-01-04 20:28:52 +0000655
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 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800660 if (available_user_process_slots() < short_term_slot_total)
661 short_term_slots =
662 available_user_process_slots() * stress_percent / 2;
iyermanoj28eaa912002-01-04 20:28:52 +0000663 else
664 short_term_slots = short_term_slot_total;
665
Wanlong Gao354ebb42012-12-07 10:10:04 +0800666 printf("\n<< Starting %d short-term testcases>> \n\n",
667 short_term_slots);
iyermanoj28eaa912002-01-04 20:28:52 +0000668 if (debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800669 printf("short-term slots available: %d\n", short_term_slots);
iyermanoj28eaa912002-01-04 20:28:52 +0000670
Wanlong Gao354ebb42012-12-07 10:10:04 +0800671 for (i = 0; i < (short_term_slots / 4); i++) {
iyermanoj28eaa912002-01-04 20:28:52 +0000672#if defined(_IA64) && !defined(__64BIT__)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800673 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000681#else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800682 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000690#endif
691#if 0
Wanlong Gao354ebb42012-12-07 10:10:04 +0800692 perform_throughput_tests(pri);
iyermanoj28eaa912002-01-04 20:28:52 +0000693#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 *-----------------------------------------------------------------------*/
702void kill_short_term_testcases()
703{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800704 int i; /* loop counter to step through the list of process id's */
iyermanoj28eaa912002-01-04 20:28:52 +0000705
Wanlong Gao354ebb42012-12-07 10:10:04 +0800706 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000707 * 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)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800712 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);
iyermanoj28eaa912002-01-04 20:28:52 +0000717 }
718
subrata_modak4bb656a2009-02-26 12:02:09 +0000719 /*
720 * Adjust the number of short_term_testcases
iyermanoj28eaa912002-01-04 20:28:52 +0000721 */
722 short_running -= numprocs;
723
subrata_modak4bb656a2009-02-26 12:02:09 +0000724 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000725 * Clear the table by setting number of entries to zero
726 */
727 numprocs = 0;
728}
729
iyermanoj28eaa912002-01-04 20:28:52 +0000730/*----------------------------- finishup() ------------------------------*/
731/* This procedure closing information to the about ending *
732 * times, elapsed times, etc. This procedure then closes the file*
733 *-----------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800734void finishup(start_time)
735long start_time; /* starting time to calculate elapsed time */
iyermanoj28eaa912002-01-04 20:28:52 +0000736{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800737 long end_time; /* time when program finished */
iyermanoj28eaa912002-01-04 20:28:52 +0000738
subrata_modak4bb656a2009-02-26 12:02:09 +0000739 /*
iyermanoj28eaa912002-01-04 20:28:52 +0000740 * Get the end time and calculate elapsed time; write all this out
741 */
Cyril Hrubis4e2bab82014-09-24 16:34:35 +0200742 end_time = time(NULL);
iyermanoj28eaa912002-01-04 20:28:52 +0000743
Wanlong Gao354ebb42012-12-07 10:10:04 +0800744 printf("\nend time = %s\n", ctime(&end_time));
iyermanoj28eaa912002-01-04 20:28:52 +0000745
Wanlong Gao354ebb42012-12-07 10:10:04 +0800746 printf("elapsed time = %4.2f hours\n",
747 ((end_time - start_time) / 3600.0));
iyermanoj28eaa912002-01-04 20:28:52 +0000748}
749
iyermanoj28eaa912002-01-04 20:28:52 +0000750/*---------------------------------------------------------------------+
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+---------------------------------------------------------------------*/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800762void parse_args(int argc, char **argv)
iyermanoj28eaa912002-01-04 20:28:52 +0000763{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800764 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 */
iyermanoj28eaa912002-01-04 20:28:52 +0000769
770 /*
771 * Parse command line options.
772 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800773 while ((opt = getopt(argc, argv, "vs:p:t:l:d")) != EOF) {
774 switch (opt) {
iyermanoj28eaa912002-01-04 20:28:52 +0000775 case 's': /* stress percentage */
776 sflg++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800777 stress_percent = atof(optarg);
iyermanoj28eaa912002-01-04 20:28:52 +0000778 break;
779 case 'p': /* process slots */
780 pflg++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800781 process_slots = atof(optarg);
iyermanoj28eaa912002-01-04 20:28:52 +0000782 break;
783 case 't': /* time (hours) */
784 tflg++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800785 execution_time = atof(optarg);
iyermanoj28eaa912002-01-04 20:28:52 +0000786 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...
Wanlong Gao354ebb42012-12-07 10:10:04 +0800801 */
subrata_modak4bb656a2009-02-26 12:02:09 +0000802 if (sflg) {
iyermanoj28eaa912002-01-04 20:28:52 +0000803 if (stress_percent < 0.0 || stress_percent > 1.0)
804 errflag++;
805 }
subrata_modak4bb656a2009-02-26 12:02:09 +0000806 if (pflg) {
iyermanoj28eaa912002-01-04 20:28:52 +0000807 if (process_slots < 0 || process_slots > MAXPROCS)
808 errflag++;
809 }
subrata_modak4bb656a2009-02-26 12:02:09 +0000810 if (tflg) {
iyermanoj28eaa912002-01-04 20:28:52 +0000811 if (execution_time < 0.0 || execution_time > 100.0)
812 errflag++;
813 }
subrata_modak4bb656a2009-02-26 12:02:09 +0000814 if (debug)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800815 printf("\n(debugging messages enabled)\n\n");
iyermanoj28eaa912002-01-04 20:28:52 +0000816 if (errflag) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800817 fprintf(stderr, USAGE, program_name);
818 exit(2);
iyermanoj28eaa912002-01-04 20:28:52 +0000819 }
Chris Dearmanec6edca2012-10-17 19:54:01 -0700820}