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 */ 85void parse_args(int, char **); 86void 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 */ 97int verbose = 0; 98int debug = 0; 99int priority = DEFAULT_PRIORITY; 100char *logfile = DEFAULT_LOGFILE; 101char *priority_type = DEFAULT_PRIORITY_TYPE; 102 103/*---------------------------------------------------------------------+ 104| main | 105| ==================================================================== | 106| | 107| Function: ... | 108| | 109+---------------------------------------------------------------------*/ 110int 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+---------------------------------------------------------------------*/ 184void 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+---------------------------------------------------------------------*/ 243void 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