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 */ 81void parse_args(int, char **); 82void 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 */ 93int verbose = 0; 94int debug = 0; 95int priority = DEFAULT_PRIORITY; 96char *logfile = DEFAULT_LOGFILE; 97char *priority_type = DEFAULT_PRIORITY_TYPE; 98 99/*---------------------------------------------------------------------+ 100| main | 101| ==================================================================== | 102| | 103| Function: ... | 104| | 105+---------------------------------------------------------------------*/ 106int 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+---------------------------------------------------------------------*/ 180void 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+---------------------------------------------------------------------*/ 246void 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