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_tc2                              |
24| ==================================================================== |
25|                                                                      |
26| Description:  Creates long-term disk I/O bound process               |
27|                                                                      |
28| Algorithm:    o  Set process priority                                |
29|               o  Open a large file and repeatedly read from it       |
30|                  for a specified time duration                       |
31|                                                                      |
32| To compile:   cc -o sched_tc2 sched_tc2.c -L. -lpsc                  |
33|                                                                      |
34| Usage:        sched_tc2 [-t sec] [-p priority] [-v] [-d]             |
35|                                                                      |
36| Last update:   Ver. 1.3, 4/10/94 23:05:01                           |
37|                                                                      |
38| Change Activity                                                      |
39|                                                                      |
40|   Version  Date    Name  Reason                                      |
41|    0.1     050689  CTU   Initial version                             |
42|    0.2     010402  Manoj Iyer Ported to Linux			       |
43|                                                                      |
44+---------------------------------------------------------------------*/
45
46#include   <stdlib.h>
47#include <sys/time.h>
48#include <sys/resource.h>
49#include   "sched.h"
50
51/*
52 * Defines:
53 *
54 * USAGE: usage statement
55 *
56 * DEFAULT_PRIORITY_TYPE: default priority
57 *
58 * DEFAULT_EXECUTION_TIME: default execution time (in seconds)
59 *
60 * DEFAULT_MATRIX_SIZE: default size of matrix
61 *
62 */
63#define DEFAULT_PRIORITY_TYPE	"variable"
64#define DEFAULT_EXECUTION_TIME	1800
65#define MATRIX_SIZE		100
66#define USAGE "Usage:  %s  [-p priority] [-t sec] [-v] [-d]      \n" \
67              "        -t sec      execution time (default 1800 sec)    \n" \
68              "        -p priority priority (default variable)          \n" \
69              "        -v          verbose                              \n" \
70              "        -d          enable debugging messages            \n"
71
72/*
73 * Function prototypes:
74 *
75 * process_file: reads data file
76 *
77 * parse_args: parse command line arguments
78 */
79void parse_args(int, char **);
80void multiply_matrices();
81
82/*
83 * Global variables:
84 *
85 * verbose: enable normal messages
86 *
87 * debug: enable debugging messages
88 *
89 * execution_time: testcase execution time (hours)
90 *
91 * priority: process type (fixed priority, variable priority)
92 */
93int verbose = 0;
94int debug = 0;
95long execution_time = DEFAULT_EXECUTION_TIME;
96char *priority = DEFAULT_PRIORITY_TYPE;
97
98/*---------------------------------------------------------------------+
99|                                 main                                 |
100| ==================================================================== |
101|                                                                      |
102| Function:  ...                                                       |
103|                                                                      |
104+---------------------------------------------------------------------*/
105int main(int argc, char **argv)
106{
107	long start_time;	/* time at start of testcase */
108	int i;
109
110	/*
111	 * Process command line arguments...
112	 */
113	if (argc < 2) {
114		fprintf(stderr, USAGE, *argv);
115		exit(0);
116	}
117
118	parse_args(argc, argv);
119	if (verbose)
120		printf("%s: Scheduler TestSuite program\n\n", *argv);
121	if (debug) {
122		printf("\tpriority:       %s\n", priority);
123		printf("\texecution_time: %ld (sec)\n", execution_time);
124	}
125
126	/*
127	 * Adjust the priority of this process if the real time flag is set
128	 */
129	if (!strcmp(priority, "fixed")) {
130#ifndef __linux__
131		if (setpri(0, DEFAULT_PRIORITY) < 0)
132			sys_error("setpri failed", __FILE__, __LINE__);
133#else
134		if (setpriority(PRIO_PROCESS, 0, 0) < 0)
135			sys_error("setpri failed", __FILE__, __LINE__);
136#endif
137	}
138
139	/*
140	 * Continuously multiply matrix as time permits...
141	 */
142	i = 0;
143	start_time = time(NULL);
144
145	if (debug)
146		printf("\n");
147	while ((time(NULL) - start_time) < execution_time) {
148		if (debug) {
149			printf("\r\tmultiplying matrix [%d], time left: %ld",
150			       i++,
151			       execution_time - (time(NULL) - start_time));
152			fflush(stdout);
153		}
154		multiply_matrices();
155	}
156	if (debug)
157		printf("\n");
158
159	/*
160	 * Exit with success!
161	 */
162	if (verbose)
163		printf("\nsuccessful!\n");
164	return (0);
165}
166
167/*---------------------------------------------------------------------+
168|                         multiply_matricies ()                        |
169| ==================================================================== |
170|                                                                      |
171| Function:  Randomly assigns two matrices values and then multiplies  |
172|            them together.                                            |
173|                                                                      |
174+---------------------------------------------------------------------*/
175void multiply_matrices()
176{
177	int i, j, k;		/* various indeces to access the arrays */
178	float matrix_1[MATRIX_SIZE][MATRIX_SIZE];
179	float matrix_2[MATRIX_SIZE][MATRIX_SIZE];
180	float matrix_3[MATRIX_SIZE][MATRIX_SIZE];
181
182	/* first, fill the two matrices to be multiplied with random values */
183
184	for (i = 0; i < MATRIX_SIZE; i++) {
185		for (j = 0; j < MATRIX_SIZE; j++) {
186			matrix_1[i][j] = (float)(rand() % 100);
187			matrix_2[i][j] = (float)(rand() % 100);
188		}
189	}
190
191	/*
192	 * Now multiply the two matrices
193	 */
194	for (i = 0; i < MATRIX_SIZE; i++) {
195		for (j = 0; j < MATRIX_SIZE; j++) {
196			matrix_3[i][j] = 0.0;	/* clear the element first */
197			for (k = 0; k < MATRIX_SIZE; k++)
198				matrix_3[i][j] +=
199				    matrix_1[i][k] * matrix_2[k][j];
200		}
201	}
202}
203
204/*---------------------------------------------------------------------+
205|                             parse_args ()                            |
206| ==================================================================== |
207|                                                                      |
208| Function:  Parse the command line arguments & initialize global      |
209|            variables.                                                |
210|                                                                      |
211| Updates:   (command line options)                                    |
212|                                                                      |
213|            [-p] priority: "fixed" or "variable"                      |
214|            [-t] n:        execution time in hours                    |
215|            [-v]           verbose                                    |
216|            [-d]           enable debugging messages                  |
217|                                                                      |
218+---------------------------------------------------------------------*/
219void parse_args(int argc, char **argv)
220{
221	int opt;
222	int pflg = 0, tflg = 0;
223	int errflag = 0;
224	char *program_name = *argv;
225	extern char *optarg;	/* Command line option */
226
227	/*
228	 * Parse command line options.
229	 */
230	if (argc < 2) {
231		fprintf(stderr, USAGE, program_name);
232		exit(0);
233	}
234
235	while ((opt = getopt(argc, argv, "p:t:vd")) != EOF) {
236		switch (opt) {
237		case 'p':	/* process type */
238			pflg++;
239			priority = optarg;
240			break;
241		case 't':	/* time (hours) */
242			tflg++;
243			execution_time = atof(optarg);
244			break;
245		case 'v':	/* verbose */
246			verbose++;
247			break;
248		case 'd':	/* enable debugging messages */
249			verbose++;
250			debug++;
251			break;
252		default:
253			errflag++;
254			break;
255		}
256	}
257
258	/*
259	 * Check percentage, execution time and process slots...
260	 */
261	if (pflg) {
262		if (strcmp(priority, "fixed") && strcmp(priority, "variable"))
263			errflag++;
264	}
265	if (tflg) {
266		if (execution_time < 0.0 || execution_time > 360000)
267			errflag++;
268	}
269	if (errflag) {
270		fprintf(stderr, USAGE, program_name);
271		exit(2);
272	}
273}
274