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