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 +---------------------------------------------------------------------*/
main(int argc,char ** argv)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 +---------------------------------------------------------------------*/
read_raw_device()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 +---------------------------------------------------------------------*/
parse_args(int argc,char ** argv)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