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