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_tc5                              |
     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_tc5 sched_tc5.c -L. -lpsc                  |
     33 |                                                                      |
     34 | Usage:        sched_tc5 [-t priority_type] [-p priority]             |
     35 |                         [-l log] [-v] [-d]                           |
     36 |                                                                      |
     37 | Last update:   Ver. 1.3, 4/10/94 23:05:03                           |
     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   <stdio.h>
     48 #include   <stdlib.h>
     49 #include   <sys/times.h>
     50 #include <sys/resource.h>
     51 #include   "sched.h"
     52 
     53 /*
     54  * Defines:
     55  *
     56  * USAGE: usage statement
     57  *
     58  * DEFAULT_PRIORITY_TYPE: default priority
     59  *
     60  * BLOCK_SIZE: block size (in bytes) for raw I/O
     61  *
     62  * TIMES: number of times preform calculations
     63  *
     64  */
     65 #define DEFAULT_PRIORITY_TYPE	"variable"
     66 #define DEFAULT_LOGFILE		"sched_tc5.log"
     67 #define TIMES			20
     68 #define MATRIX_SIZE    		50
     69 #define USAGE "Usage:  %s  [-l log] [-t type] [-p priority] [-v] [-d]\n" \
     70               "        -l log      log file                             \n" \
     71               "        -t type     priority type 'variable' or 'fixed'  \n" \
     72               "        -p priority priority value                       \n" \
     73               "        -v          verbose                              \n" \
     74               "        -d          enable debugging messages            \n"
     75 
     76 /*
     77  * Function prototypes:
     78  *
     79  * parse_args: parse command line arguments
     80  */
     81 void parse_args(int, char **);
     82 void invert_matrix();
     83 
     84 /*
     85  * Global variables:
     86  *
     87  * verbose: enable normal messages
     88  *
     89  * debug: enable debugging messages
     90  *
     91  * priority: process type (fixed priority, variable priority)
     92  */
     93 int verbose = 0;
     94 int debug = 0;
     95 int priority = DEFAULT_PRIORITY;
     96 char *logfile = DEFAULT_LOGFILE;
     97 char *priority_type = DEFAULT_PRIORITY_TYPE;
     98 
     99 /*---------------------------------------------------------------------+
    100 |                                 main                                 |
    101 | ==================================================================== |
    102 |                                                                      |
    103 | Function:  ...                                                       |
    104 |                                                                      |
    105 +---------------------------------------------------------------------*/
    106 int main(int argc, char **argv)
    107 {
    108 	FILE *statfile;
    109 	int i;
    110 	clock_t start_time;	/* start & stop times */
    111 	clock_t stop_time;
    112 	float elapsed_time;
    113 	struct tms timer_info;	/* time accounting info */
    114 
    115 	/*
    116 	 * Process command line arguments...
    117 	 */
    118 	parse_args(argc, argv);
    119 	if (verbose)
    120 		printf("%s: Scheduler TestSuite program\n\n", *argv);
    121 	if (debug) {
    122 		printf("\tpriority type:  %s\n", priority_type);
    123 		printf("\tpriority:       %d\n", priority);
    124 		printf("\tlogfile:        %s\n", logfile);
    125 	}
    126 
    127 	/*
    128 	 * Adjust the priority of this process if the real time flag is set
    129 	 */
    130 	if (!strcmp(priority_type, "fixed")) {
    131 #ifndef __linux__
    132 		if (setpri(0, DEFAULT_PRIORITY) < 0)
    133 			sys_error("setpri failed", __FILE__, __LINE__);
    134 #else
    135 		if (setpriority(PRIO_PROCESS, 0, 0) < 0)
    136 			sys_error("setpri failed", __FILE__, __LINE__);
    137 #endif
    138 	} else {
    139 		if (nice((priority - 50) - (nice(0) + 20)) < 0 && errno != 0)
    140 			sys_error("nice failed", __FILE__, __LINE__);
    141 	}
    142 
    143 	/*
    144 	 * Read from raw I/O device and record elapsed time...
    145 	 */
    146 	start_time = time((time_t *) & timer_info);
    147 
    148 	for (i = 0; i < TIMES; i++)
    149 		invert_matrix();
    150 
    151 	stop_time = time((time_t *) & timer_info);
    152 	elapsed_time = (float)(stop_time - start_time) / 100.0;
    153 
    154 	if ((statfile = fopen(logfile, "w")) == NULL)
    155 		sys_error("fopen failed", __FILE__, __LINE__);
    156 
    157 	fprintf(statfile, "%f\n", elapsed_time);
    158 	if (debug)
    159 		printf("\n\telapsed time: %f\n", elapsed_time);
    160 
    161 	if (fclose(statfile) < 0)
    162 		sys_error("fclose failed", __FILE__, __LINE__);
    163 
    164 	/*
    165 	 * Exit with success!
    166 	 */
    167 	if (verbose)
    168 		printf("\nsuccessful!\n");
    169 	return (0);
    170 }
    171 
    172 /*---------------------------------------------------------------------+
    173 |                           invert_matrix ()                           |
    174 | ==================================================================== |
    175 |                                                                      |
    176 | Function:  o  Randomly assign values to a matrix and then calculate  |
    177 |               inverse..                                              |
    178 |                                                                      |
    179 +---------------------------------------------------------------------*/
    180 void invert_matrix()
    181 {
    182 	int i, j, k;
    183 	float t1;
    184 	float matrix_1[MATRIX_SIZE][MATRIX_SIZE];
    185 	float matrix_2[MATRIX_SIZE][MATRIX_SIZE];
    186 
    187 	/*
    188 	 * Fill the first matrix to be inverted with random values
    189 	 */
    190 	printf("sched_tc5: invert_matrix: before first matrix inversion\n");
    191 	for (i = 0; i < MATRIX_SIZE; i++)
    192 		for (j = 0; j < MATRIX_SIZE; j++) {
    193 			matrix_1[i][j] = (float)(rand() % 100);
    194 		}
    195 
    196 	/*
    197 	 * Now calculate the inverse of the random matrix first, create an
    198 	 * identity matrix in the result matrix
    199 	 */
    200 	printf("sched_tc5: invert_matrix: before second matrix inversion\n");
    201 	for (i = 0; i < MATRIX_SIZE; i++)
    202 		for (j = 0; j < MATRIX_SIZE; j++)
    203 			if (i == j)
    204 				matrix_2[i][j] = 1;
    205 			else
    206 				matrix_2[i][j] = 0;
    207 
    208 	printf("sched_tc5: invert_matrix: before form identity matrix\n");
    209 	/*
    210 	 * Form an identity matrix in the random matrix
    211 	 */
    212 	for (i = 0; i < MATRIX_SIZE; i++) {
    213 		t1 = matrix_1[i][i];
    214 		for (j = 0; j < MATRIX_SIZE; j++) {
    215 			matrix_1[i][j] /= t1;
    216 			matrix_2[i][j] /= t1;
    217 		}
    218 		for (j = 0; j < MATRIX_SIZE; j++)
    219 			if (i != j) {
    220 				t1 = -matrix_1[j][i];
    221 				for (k = 0; k < MATRIX_SIZE; k++) {
    222 					matrix_1[j][k] += (matrix_1[i][k] * t1);
    223 					matrix_2[j][k] += (matrix_2[i][k] * t1);
    224 				}
    225 			}
    226 	}
    227 	printf("sched_tc5: invert_matrix: after form identity matrix\n");
    228 }
    229 
    230 /*---------------------------------------------------------------------+
    231 |                             parse_args ()                            |
    232 | ==================================================================== |
    233 |                                                                      |
    234 | Function:  Parse the command line arguments & initialize global      |
    235 |            variables.                                                |
    236 |                                                                      |
    237 | Updates:   (command line options)                                    |
    238 |                                                                      |
    239 |            [-t] type:     priority type "fixed" or "variable"        |
    240 |            [-p] priority: priority value                             |
    241 |            [-l] logfile:  log file name                              |
    242 |            [-v]           verbose                                    |
    243 |            [-d]           enable debugging messages                  |
    244 |                                                                      |
    245 +---------------------------------------------------------------------*/
    246 void parse_args(int argc, char **argv)
    247 {
    248 	int opt;
    249 	int lflg = 0, pflg = 0, tflg = 0;
    250 	int errflag = 0;
    251 	char *program_name = *argv;
    252 	extern char *optarg;	/* Command line option */
    253 
    254 	/*
    255 	 * Parse command line options.
    256 	 */
    257 	if (argc < 2) {
    258 		fprintf(stderr, USAGE, program_name);
    259 		exit(0);
    260 	}
    261 
    262 	while ((opt = getopt(argc, argv, "l:t:p:vd")) != EOF) {
    263 		switch (opt) {
    264 		case 'l':	/* log file */
    265 			lflg++;
    266 			logfile = optarg;
    267 			break;
    268 		case 't':	/* process type */
    269 			tflg++;
    270 			priority_type = optarg;
    271 			break;
    272 		case 'p':	/* process priority */
    273 			pflg++;
    274 			priority = atoi(optarg);
    275 			break;
    276 		case 'v':	/* verbose */
    277 			verbose++;
    278 			break;
    279 		case 'd':	/* enable debugging messages */
    280 			verbose++;
    281 			debug++;
    282 			break;
    283 		default:
    284 			errflag++;
    285 			break;
    286 		}
    287 	}
    288 	debug = 1;
    289 
    290 	/*
    291 	 * Check percentage and process slots...
    292 	 */
    293 	if (tflg) {
    294 		if (strcmp(priority_type, "fixed") &&
    295 		    strcmp(priority_type, "variable"))
    296 			errflag++;
    297 	}
    298 	if (pflg) {
    299 		if (priority < 50 || priority > 100)
    300 			errflag++;
    301 	}
    302 	if (errflag) {
    303 		fprintf(stderr, USAGE, program_name);
    304 		exit(2);
    305 	}
    306 }
    307