Home | History | Annotate | Download | only in sched_stress
      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  * FUNCTIONS: Scheduler Test Suite
     20  */
     21 
     22 /*---------------------------------------------------------------------+
     23 |                               sched_tc4                              |
     24 | ==================================================================== |
     25 |                                                                      |
     26 | Description:  Creates short-term disk I/O bound process              |
     27 |                                                                      |
     28 | Algorithm:    o  Set process priority                                |
     29 |               o  Continuously multiply matrices together until       |
     30 |                  interrupted.                                        |
     31 |                                                                      |
     32 | To compile:   cc -o sched_tc4 sched_tc4.c -L. -lpsc                  |
     33 |                                                                      |
     34 | Usage:        sched_tc4 [-t priority_type] [-p priority]             |
     35 |                         [-l log] [-v] [-d]                           |
     36 |                                                                      |
     37 | Last update:   Ver. 1.3, 4/10/94 23:05:02                           |
     38 |                                                                      |
     39 | Change Activity                                                      |
     40 |                                                                      |
     41 |   Version  Date    Name  Reason                                      |
     42 |    0.1     050689  CTU   Initial version                             |
     43 |    0.2     010402  Manoj Iyer Ported to Linux			       |
     44 |                                                                      |
     45 +---------------------------------------------------------------------*/
     46 
     47 #include   <sys/times.h>
     48 #include <sys/resource.h>
     49 #include <sys/types.h>
     50 #include <sys/stat.h>
     51 #include <fcntl.h>
     52 #include   <stdlib.h>
     53 #include   "sched.h"
     54 
     55 /*
     56  * Defines:
     57  *
     58  * USAGE: usage statement
     59  *
     60  * DEFAULT_PRIORITY_TYPE: default priority
     61  *
     62  * BLOCK_SIZE: block size (in bytes) for raw I/O
     63  *
     64  * TIMES: number of times to read raw I/O device (~25MB)
     65  *
     66  */
     67 #define DEFAULT_PRIORITY_TYPE	"variable"
     68 #define DEFAULT_LOGFILE		"sched_tc4.log"
     69 #define BLOCK_SIZE		512
     70 #define TIMES			5000
     71 #define USAGE "Usage:  %s  [-l log] [-t type] [-p priority] [-v] [-d]\n" \
     72               "        -l log      log file                             \n" \
     73               "        -t type     priority type 'variable' or 'fixed'  \n" \
     74               "        -p priority priority value                       \n" \
     75               "        -v          verbose                              \n" \
     76               "        -d          enable debugging messages            \n"
     77 
     78 /*
     79  * Function prototypes:
     80  *
     81  * process_file: reads data file
     82  *
     83  * parse_args: parse command line arguments
     84  */
     85 void parse_args(int, char **);
     86 void read_raw_device();
     87 
     88 /*
     89  * Global variables:
     90  *
     91  * verbose: enable normal messages
     92  *
     93  * debug: enable debugging messages
     94  *
     95  * priority: process type (fixed priority, variable priority)
     96  */
     97 int verbose = 0;
     98 int debug = 0;
     99 int priority = DEFAULT_PRIORITY;
    100 char *logfile = DEFAULT_LOGFILE;
    101 char *priority_type = DEFAULT_PRIORITY_TYPE;
    102 
    103 /*---------------------------------------------------------------------+
    104 |                                 main                                 |
    105 | ==================================================================== |
    106 |                                                                      |
    107 | Function:  ...                                                       |
    108 |                                                                      |
    109 +---------------------------------------------------------------------*/
    110 int main(int argc, char **argv)
    111 {
    112 	FILE *statfile;
    113 	clock_t start_time;	/* start & stop times */
    114 	clock_t stop_time;
    115 	float elapsed_time;
    116 	struct tms timer_info;	/* time accounting info */
    117 
    118 	/*
    119 	 * Process command line arguments...
    120 	 */
    121 	parse_args(argc, argv);
    122 	if (verbose)
    123 		printf("%s: Scheduler TestSuite program\n\n", *argv);
    124 	if (debug) {
    125 		printf("\tpriority type:  %s\n", priority_type);
    126 		printf("\tpriority:       %d\n", priority);
    127 		printf("\tlogfile:        %s\n", logfile);
    128 	}
    129 
    130 	/*
    131 	 * Adjust the priority of this process if the real time flag is set
    132 	 */
    133 	if (!strcmp(priority_type, "fixed")) {
    134 #ifndef __linux__
    135 		if (setpri(0, DEFAULT_PRIORITY) < 0)
    136 			sys_error("setpri failed", __FILE__, __LINE__);
    137 #else
    138 		if (setpriority(PRIO_PROCESS, 0, 0) < 0)
    139 			sys_error("setpri failed", __FILE__, __LINE__);
    140 #endif
    141 	} else {
    142 		if (nice((priority - 50) - (nice(0) + 20)) < 0 && errno != 0)
    143 			sys_error("nice failed", __FILE__, __LINE__);
    144 	}
    145 
    146 	/*
    147 	 * Read from raw I/O device and record elapsed time...
    148 	 */
    149 	start_time = time((time_t *) & timer_info);
    150 
    151 	read_raw_device();
    152 
    153 	stop_time = time((time_t *) & timer_info);
    154 	elapsed_time = (float)(stop_time - start_time) / 100.0;
    155 
    156 	if ((statfile = fopen(logfile, "w")) == NULL)
    157 		sys_error("fopen failed", __FILE__, __LINE__);
    158 
    159 	fprintf(statfile, "%f\n", elapsed_time);
    160 	if (debug)
    161 		printf("\n\telapsed time: %f\n", elapsed_time);
    162 
    163 	if (fclose(statfile) < 0)
    164 		sys_error("fclose failed", __FILE__, __LINE__);
    165 
    166 	/*
    167 	 * Exit with success!
    168 	 */
    169 	if (verbose)
    170 		printf("\nsuccessful!\n");
    171 	return (0);
    172 }
    173 
    174 /*---------------------------------------------------------------------+
    175 |                          read_raw_device ()                          |
    176 | ==================================================================== |
    177 |                                                                      |
    178 | Function:  o  opens raw disk device                                  |
    179 |            o  reads block of size BLOCK_SIZE n times                 |
    180 |            o  lseeks back to beginning of file                       |
    181 |            o  closes raw device                                      |
    182 |                                                                      |
    183 +---------------------------------------------------------------------*/
    184 void read_raw_device()
    185 {
    186 	char readbuf[BLOCK_SIZE + 1];	/* buffer to store bytes read */
    187 	int fd;			/* file descriptor */
    188 	int i;			/* loop counter */
    189 	int blocks = 0;		/* number of blocks read */
    190 #ifndef __linux__
    191 	char raw_dev[50] = "/dev/hd2";	/* name of raw device file */
    192 #else
    193 	char *raw_dev;		/* name of raw device file  */
    194 
    195 	if ((raw_dev = getenv("RAWDEV")) == NULL) {
    196 		errno = ENODATA;
    197 		sys_error("environment variable RAWDEV not set", __FILE__,
    198 			  __LINE__);
    199 	}
    200 #endif
    201 
    202 	/*
    203 	 * Open the raw disk file
    204 	 */
    205 	if ((fd = open(raw_dev, 0)) < 0)
    206 		sys_error("open failed", __FILE__, __LINE__);
    207 
    208 	/*
    209 	 * Read through predefined number of blocks TIMES number of times.
    210 	 * (Seek back to beginning of raw device after reading 10MB)
    211 	 */
    212 	for (i = 0; i < TIMES; i++) {
    213 		if (read(fd, readbuf, BLOCK_SIZE) != BLOCK_SIZE)
    214 			sys_error("read failed", __FILE__, __LINE__);
    215 		if (blocks == 10000)
    216 			if (lseek(fd, 0, 0) < 0)
    217 				sys_error("lseek failed", __FILE__, __LINE__);
    218 	}
    219 
    220 	/*
    221 	 * Close the raw disk file
    222 	 */
    223 	if (close(fd) < 0)
    224 		sys_error("close failed", __FILE__, __LINE__);
    225 }
    226 
    227 /*---------------------------------------------------------------------+
    228 |                             parse_args ()                            |
    229 | ==================================================================== |
    230 |                                                                      |
    231 | Function:  Parse the command line arguments & initialize global      |
    232 |            variables.                                                |
    233 |                                                                      |
    234 | Updates:   (command line options)                                    |
    235 |                                                                      |
    236 |            [-t] type:     priority type "fixed" or "variable"        |
    237 |            [-p] priority: priority value                             |
    238 |            [-l] logfile:  log file name                              |
    239 |            [-v]           verbose                                    |
    240 |            [-d]           enable debugging messages                  |
    241 |                                                                      |
    242 +---------------------------------------------------------------------*/
    243 void parse_args(int argc, char **argv)
    244 {
    245 	int opt;
    246 	int lflg = 0, pflg = 0, tflg = 0;
    247 	int errflag = 0;
    248 	char *program_name = *argv;
    249 	extern char *optarg;	/* Command line option */
    250 
    251 	/*
    252 	 * Parse command line options.
    253 	 */
    254 	if (argc < 2) {
    255 		fprintf(stderr, USAGE, program_name);
    256 		exit(0);
    257 	}
    258 
    259 	while ((opt = getopt(argc, argv, "l:t:p:vd")) != EOF) {
    260 		switch (opt) {
    261 		case 'l':	/* log file */
    262 			lflg++;
    263 			logfile = optarg;
    264 			break;
    265 		case 't':	/* process type */
    266 			tflg++;
    267 			priority_type = optarg;
    268 			break;
    269 		case 'p':	/* process priority */
    270 			pflg++;
    271 			priority = atoi(optarg);
    272 			break;
    273 		case 'v':	/* verbose */
    274 			verbose++;
    275 			break;
    276 		case 'd':	/* enable debugging messages */
    277 			verbose++;
    278 			debug++;
    279 			break;
    280 		default:
    281 			errflag++;
    282 			break;
    283 		}
    284 	}
    285 
    286 	/*
    287 	 * Check percentage and process slots...
    288 	 */
    289 	if (tflg) {
    290 		if (strcmp(priority_type, "fixed") &&
    291 		    strcmp(priority_type, "variable")) {
    292 			errflag++;
    293 			fprintf(stderr, "Error: priority type must be: "
    294 				"\'fixed\' or \'variable\'\n");
    295 		}
    296 	}
    297 	if (pflg) {
    298 		if (priority < 50 || priority > 100) {
    299 			errflag++;
    300 			fprintf(stderr, "Error: priority range [50..100]\n");
    301 		}
    302 	}
    303 	if (errflag) {
    304 		fprintf(stderr, USAGE, program_name);
    305 		exit(2);
    306 	}
    307 }
    308