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 /* FUNCTIONS: Scheduler Test Suite */
19 
20 /*---------------------------------------------------------------------+
21 |                               sched_tc1                              |
22 | ==================================================================== |
23 |                                                                      |
24 | Description:  Creates short-term disk I/O bound process              |
25 |                                                                      |
26 | Algorithm:    o  Set process priority                                |
27 |               o  Open a large file                                   |
28 |               o  Continuously read from file until interrupted       |
29 |               o  Close file upon receiving interrupt                 |
30 |                                                                      |
31 | To compile:   cc -o sched_tc1 sched_tc1.c -L. -lpsc                  |
32 |                                                                      |
33 | Usage:        sched_tc1 [-p priority] [-v] [-d]                      |
34 |                                                                      |
35 | Last update:   Ver. 1.4, 4/10/94 23:05:00                           |
36 |                                                                      |
37 | Change Activity                                                      |
38 |                                                                      |
39 |   Version  Date    Name  Reason                                      |
40 |    0.1     050689  CTU   Initial version                             |
41 |    0.2     010402  Manoj Iyer Ported to Linux			       |
42 |                                                                      |
43 +---------------------------------------------------------------------*/
44 
45 #include   <stdlib.h>
46 #include   <signal.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  */
59 #define DEFAULT_PRIORITY_TYPE	"variable"
60 #define USAGE "Usage:  %s  [-p priority] [-v] [-d]               \n" \
61               "        -p priority priority (default variable)          \n" \
62               "        -v          verbose                              \n" \
63               "        -d          enable debugging messages            \n"
64 
65 /*
66  * Function prototypes:
67  *
68  * process_file: reads data file
69  *
70  * parse_args: parse command line arguments
71  */
72 void process_file(char *);
73 void parse_args(int, char **);
74 void signal_handler();
75 
76 /*
77  * Global variables:
78  *
79  * verbose: enable normal messages
80  *
81  * debug: enable debugging messages
82  *
83  * signaled: set upon receiving SIGUSER1 signal
84  *
85  * priority: process type (fixed priority, variable priority)
86  */
87 int verbose = 0;
88 int debug = 0;
89 int signaled = 0;
90 char *priority = DEFAULT_PRIORITY_TYPE;
91 
92 /*---------------------------------------------------------------------+
93 |                                 main                                 |
94 | ==================================================================== |
95 |                                                                      |
96 | Function:  ...                                                       |
97 |                                                                      |
98 +---------------------------------------------------------------------*/
main(int argc,char ** argv)99 int main(int argc, char **argv)
100 {
101 	char *filename = NULL;
102 
103 	if ((filename = getenv("KERNEL")) == NULL) {
104 		errno = ENODATA;
105 		sys_error("environment variable KERNEL not set", __FILE__,
106 			  __LINE__);
107 	}
108 	/*
109 	 * Setup signal handler & setup alarm so we do not loop forever...
110 	 */
111 	signal(SIGUSR1, signal_handler);
112 	signal(SIGALRM, signal_handler);
113 	alarm(600);		/* wait 10 minutes before aborting */
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:       %s\n", priority);
123 	}
124 
125 	/*
126 	 * Adjust the priority of this process if the real time flag is set
127 	 */
128 	if (!strcmp(priority, "fixed")) {
129 #ifndef __linux__
130 		if (setpri(0, DEFAULT_PRIORITY) < 0)
131 			sys_error("setpri failed", __FILE__, __LINE__);
132 #else
133 		if (setpriority(PRIO_PROCESS, 0, 0) < 0)
134 			sys_error("setpri failed", __FILE__, __LINE__);
135 #endif
136 	}
137 
138 	/*
139 	 * Continuously read through file until interrupted...
140 	 */
141 	while (!signaled)
142 		process_file(filename);
143 
144 	/*
145 	 * Exit with success!
146 	 */
147 	if (verbose)
148 		printf("\nsuccessful!\n");
149 	return (0);
150 }
151 
152 /*---------------------------------------------------------------------+
153 |                            process_file ()                           |
154 | ==================================================================== |
155 |                                                                      |
156 | Function:  Opens a file, reads from it until it encounters an        |
157 |            end-of-file and then closes the file..                    |
158 |                                                                      |
159 +---------------------------------------------------------------------*/
process_file(char * filename)160 void process_file(char *filename)
161 {
162 	char record[100];	/* holds each record of the file read */
163 	FILE *datafile;		/* file pointer to the open file */
164 
165 	/*
166 	 * Try and open the datafile
167 	 */
168 	if ((datafile = fopen(filename, "r")) == NULL)
169 		sys_error("fopen failed", __FILE__, __LINE__);
170 
171 	/*
172 	 * Read the first record of the datafile, then read until end-of-file
173 	 */
174 	while (fgets(record, 80, datafile)) {
175 		if (feof(datafile))
176 			break;
177 	}
178 
179 	/*
180 	 * Close the datafile
181 	 */
182 	if (fclose(datafile))
183 		sys_error("fclose failed", __FILE__, __LINE__);
184 }
185 
186 /*---------------------------------------------------------------------+
187 |                           signal_handler ()                          |
188 | ==================================================================== |
189 |                                                                      |
190 | Function:  ...                                                       |
191 |                                                                      |
192 +---------------------------------------------------------------------*/
signal_handler(int signal)193 void signal_handler(int signal)
194 {
195 	printf("signal received is %d\n", signal);
196 	if (signal == SIGUSR1) {
197 		signaled++;
198 		if (debug)
199 			printf("\n\t<< caught SIGUSR1 interrupt>>\n");
200 	} else if (signal == SIGALRM) {
201 		error("Failed to receive SIGUSR1 signal before timeout!",
202 		      __FILE__, __LINE__);
203 	} else
204 		error("received unexpected signal", __FILE__, __LINE__);
205 }
206 
207 /*---------------------------------------------------------------------+
208 |                             parse_args ()                            |
209 | ==================================================================== |
210 |                                                                      |
211 | Function:  Parse the command line arguments & initialize global      |
212 |            variables.                                                |
213 |                                                                      |
214 | Updates:   (command line options)                                    |
215 |                                                                      |
216 |            [-p] priority: "fixed" or "variable"                      |
217 |            [-t] n:        execution time in hours                    |
218 |            [-v]           verbose                                    |
219 |            [-d]           enable debugging messages                  |
220 |                                                                      |
221 +---------------------------------------------------------------------*/
parse_args(int argc,char ** argv)222 void parse_args(int argc, char **argv)
223 {
224 	int opt;
225 	int pflg = 0;
226 	int errflag = 0;
227 	char *program_name = *argv;
228 	extern char *optarg;	/* Command line option */
229 
230 	/*
231 	 * Parse command line options.
232 	 */
233 	if (argc < 2) {
234 		fprintf(stderr, USAGE, program_name);
235 		exit(0);
236 	}
237 
238 	while ((opt = getopt(argc, argv, "p:t:vd")) != EOF) {
239 		switch (opt) {
240 		case 'p':	/* process type */
241 			pflg++;
242 			priority = optarg;
243 			break;
244 		case 'v':	/* verbose */
245 			verbose++;
246 			break;
247 		case 'd':	/* enable debugging messages */
248 			verbose++;
249 			debug++;
250 			break;
251 		default:
252 			errflag++;
253 			break;
254 		}
255 	}
256 
257 	/*
258 	 * Check percentage, execution time and process slots...
259 	 */
260 	if (pflg) {
261 		if (strcmp(priority, "fixed") && strcmp(priority, "variable"))
262 			errflag++;
263 	}
264 	if (errflag) {
265 		fprintf(stderr, USAGE, program_name);
266 		exit(2);
267 	}
268 }
269