source: liacs/os/assignment3/nutt-lab-6-1.c@ 372

Last change on this file since 372 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

File size: 10.4 KB
Line 
1/*
2 * Rick van der Zwet
3 * 0433373
4 * OS Assigment 3 - Part B
5 * Licence: BSD
6 * $Id: partBCD.c 508 2008-03-02 14:18:40Z rick $
7 */
8
9 /* XXX: Code is rather verbose and has got a lot of duplicate lines */
10
11#include <sys/time.h>
12#include <sys/types.h>
13#include <sys/wait.h>
14#include <signal.h>
15#include <unistd.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <sysexits.h>
19
20long unsigned int elapsed_usecs(long sec, long usec);
21long unsigned int fibonacci(unsigned int n);
22long unsigned int delta_time(struct itimerval proft, struct itimerval
23realt);
24static void p_sig_handler(int);
25static void c1_sig_handler(int);
26static void c2_sig_handler(int);
27
28//These variables are used to record the accumulated times. They are set
29//by the signal handlers and read by the process when the report the
30//results
31
32static long p_realt_secs = 0, c1_realt_secs = 0, c2_realt_secs = 0;
33static long p_virtt_secs = 0, c1_virtt_secs = 0, c2_virtt_secs = 0;
34static long p_proft_secs = 0, c1_proft_secs = 0, c2_proft_secs = 0;
35static struct itimerval p_realt, c1_realt, c2_realt;
36static struct itimerval p_virtt, c1_virtt, c2_virtt;
37static struct itimerval p_proft, c1_proft, c2_proft;
38
39int main(int argc, char ** argv) {
40 long unsigned fib = 0;
41 int pid1, pid2;
42 unsigned int fibarg;
43 int status;
44
45 //Get command line argument, fibarg (the value N in the problem
46 //statement)
47 if (argc < 2) {
48 fprintf(stderr, "Usage: %s <number>\n", argv[0]);
49 exit(EX_USAGE);
50 }
51
52 fibarg = atoi(argv[1]);
53 printf("Calculating fibonacci number: %i\n", fibarg);
54
55 //Initialize parent, child1 and child 2 timer values
56 //XXX: Any quicker way of doing this?
57 p_realt.it_interval.tv_sec = 1;
58 p_realt.it_interval.tv_usec = 0;
59 p_realt.it_value.tv_sec = 1;
60 p_realt.it_value.tv_usec = 0;
61 p_virtt.it_interval.tv_sec = 1;
62 p_virtt.it_interval.tv_usec = 0;
63 p_virtt.it_value.tv_sec = 1;
64 p_virtt.it_value.tv_usec = 0;
65 p_proft.it_interval.tv_sec = 1;
66 p_proft.it_interval.tv_usec = 0;
67 p_proft.it_value.tv_sec = 1;
68 p_proft.it_value.tv_usec = 0;
69
70 c1_realt.it_interval.tv_sec = 1;
71 c1_realt.it_interval.tv_usec = 0;
72 c1_realt.it_value.tv_sec = 1;
73 c1_realt.it_value.tv_usec = 0;
74 c1_virtt.it_interval.tv_sec = 1;
75 c1_virtt.it_interval.tv_usec = 0;
76 c1_virtt.it_value.tv_sec = 1;
77 c1_virtt.it_value.tv_usec = 0;
78 c1_proft.it_interval.tv_sec = 1;
79 c1_proft.it_interval.tv_usec = 0;
80 c1_proft.it_value.tv_sec = 1;
81 c1_proft.it_value.tv_usec = 0;
82
83 c2_realt.it_interval.tv_sec = 1;
84 c2_realt.it_interval.tv_usec = 0;
85 c2_realt.it_value.tv_sec = 1;
86 c2_realt.it_value.tv_usec = 0;
87 c2_virtt.it_interval.tv_sec = 1;
88 c2_virtt.it_interval.tv_usec = 0;
89 c2_virtt.it_value.tv_sec = 1;
90 c2_virtt.it_value.tv_usec = 0;
91 c2_proft.it_interval.tv_sec = 1;
92 c2_proft.it_interval.tv_usec = 0;
93 c2_proft.it_value.tv_sec = 1;
94 c2_proft.it_value.tv_usec = 0;
95
96 //Enable parent's signal handlers
97 signal(SIGALRM, p_sig_handler);
98 signal(SIGVTALRM, p_sig_handler);
99 signal(SIGPROF, p_sig_handler);
100
101 //Set parent itimers
102 if(setitimer(ITIMER_REAL, &p_realt, NULL) == -1)
103 perror("parent real timer set error");
104 if(setitimer(ITIMER_VIRTUAL, &p_virtt, NULL) == -1)
105 perror("parent virtual timer set error");
106 if(setitimer(ITIMER_PROF, &p_proft, NULL) == -1)
107 perror("parent profile timer set error");
108
109 pid1 = fork();
110 if (pid1 == 0) {
111 // Enable child 1 signal handlers (disable parent handlers)
112 signal(SIGALRM, c1_sig_handler);
113 signal(SIGVTALRM, c1_sig_handler);
114 signal(SIGPROF, c1_sig_handler);
115
116 // Enable child 1 signal handlers
117
118 // Set child 1 itimers
119 if(setitimer(ITIMER_REAL, &c1_realt, NULL) == -1)
120 perror("parent real timer set error");
121 if(setitimer(ITIMER_VIRTUAL, &c1_virtt, NULL) == -1)
122 perror("parent virtual timer set error");
123 if(setitimer(ITIMER_PROF, &c1_proft, NULL) == -1)
124 perror("parent profile timer set error");
125
126 // Start child 1 on the fibonacci program
127 fib = fibonacci(fibarg);
128
129 // Read child 1 itimer values and report them
130 getitimer(ITIMER_PROF, &c1_proft);
131 getitimer(ITIMER_REAL, &c1_realt);
132 getitimer(ITIMER_VIRTUAL, &c1_virtt);
133 printf("\n");
134 printf("Child 1 fib = %ld, real time = %ld sec, %ld msec\n",
135 fib, c1_realt_secs,
136 elapsed_usecs(c1_realt.it_value.tv_sec,
137 c2_realt.it_value.tv_usec) / 1000);
138 printf("Child 1 fib = %ld, cpu time = %ld sec, %ld msec\n",
139 fib, c1_proft_secs,
140 elapsed_usecs(c1_proft.it_value.tv_sec,
141 c2_proft.it_value.tv_usec) / 1000);
142 printf("Child 1 fib = %ld, user time = %ld sec, %ld msec\n",
143 fib, c1_virtt_secs,
144 elapsed_usecs(c1_virtt.it_value.tv_sec,
145 c2_virtt.it_value.tv_usec) / 1000);
146
147 printf("Child 1 fib = %ld, kernel time = %ld sec, %ld msec\n",
148 fib, delta_time(c1_proft, c1_virtt),
149 (elapsed_usecs(c1_proft.it_value.tv_sec,
150 c1_proft.it_value.tv_usec) / 1000) -
151 (elapsed_usecs(c1_virtt.it_value.tv_sec,
152 c1_virtt.it_value.tv_usec) / 1000));
153 fflush(stdout);
154 exit(0);
155 } else {
156 pid2 = fork();
157 if (pid2 == 0) {
158 //Enable child 2 signal handlers
159 signal(SIGALRM, c2_sig_handler);
160 signal(SIGVTALRM, c2_sig_handler);
161 signal(SIGPROF, c2_sig_handler);
162
163 //Set child 2 itimers
164 if(setitimer(ITIMER_REAL, &c2_realt, NULL) == -1)
165 perror("parent real timer set error");
166 if(setitimer(ITIMER_VIRTUAL, &c2_virtt, NULL) == -1)
167 perror("parent virtual timer set error");
168 if(setitimer(ITIMER_PROF, &c2_proft, NULL) == -1)
169 perror("parent profile timer set error");
170
171 //Start child 2 on the fibonacci program
172 fib = fibonacci(fibarg);
173
174 //Read child 2 itimer values and report them
175 getitimer(ITIMER_PROF, &c2_proft);
176 getitimer(ITIMER_REAL, &c2_realt);
177 getitimer(ITIMER_VIRTUAL, &c2_virtt);
178 printf("\n");
179 printf("Child 2 fib = %ld, real time = %ld sec, %ld msec\n",
180 fib, c2_realt_secs,
181 elapsed_usecs(c2_realt.it_value.tv_sec,
182 c2_realt.it_value.tv_usec) / 1000);
183 printf("Child 2 fib = %ld, cpu time = %ld sec, %ld msec\n",
184 fib, c2_proft_secs,
185 elapsed_usecs(c2_proft.it_value.tv_sec,
186 c2_proft.it_value.tv_usec) / 1000);
187 printf("Child 2 fib = %ld, user time = %ld sec, %ld msec\n",
188 fib, c2_virtt_secs,
189 elapsed_usecs(c2_virtt.it_value.tv_sec,
190 c2_virtt.it_value.tv_usec) / 1000);
191
192 printf("Child 2 fib = %ld, kernel time = %ld sec, %ld msec\n",
193 fib, delta_time(c2_proft, c2_virtt),
194 (elapsed_usecs(c2_proft.it_value.tv_sec,
195 c2_proft.it_value.tv_usec) / 1000) -
196 (elapsed_usecs(c2_virtt.it_value.tv_sec,
197 c2_virtt.it_value.tv_usec) / 1000));
198 fflush(stdout);
199 exit(0);
200 } else { /*This is the parent */
201 //Start parent on the fibonacci program
202 fib = fibonacci(fibarg);
203
204 // Wait for childen to terminate
205 waitpid(0, &status, 0);
206 waitpid(0, &status, 0);
207
208 // Read parent itimer values and report them
209 getitimer(ITIMER_PROF, &p_proft);
210 getitimer(ITIMER_REAL, &p_realt);
211 getitimer(ITIMER_VIRTUAL, &p_virtt);
212 printf("\n");
213 printf("Parent fib = %ld, real time = %ld sec, %ld msec\n",
214 fib, p_realt_secs,
215 elapsed_usecs(p_realt.it_value.tv_sec,
216 p_realt.it_value.tv_usec) / 1000);
217 printf("Parent fib = %ld, cpu time = %ld sec, %ld msec\n",
218 fib, p_proft_secs,
219 elapsed_usecs(p_proft.it_value.tv_sec,
220 p_proft.it_value.tv_usec) / 1000);
221 printf("Parent fib = %ld, user time = %ld sec, %ld msec\n",
222 fib, p_virtt_secs,
223 elapsed_usecs(p_virtt.it_value.tv_sec,
224 p_virtt.it_value.tv_usec) / 1000);
225
226 printf("Parent fib = %ld, kernel time = %ld sec, %ld msec\n",
227 fib, delta_time(p_proft, p_virtt),
228 (elapsed_usecs(p_proft.it_value.tv_sec,
229 p_proft.it_value.tv_usec) / 1000) -
230 (elapsed_usecs(p_virtt.it_value.tv_sec,
231 p_virtt.it_value.tv_usec) / 1000));
232 fflush(stdout);
233 exit(0);
234 }
235 }
236 return(0);
237}
238
239static void p_sig_handler(int signo) {
240 printf("Signal handler parent, signal %i\n", signo);
241 switch (signo) {
242 case SIGALRM:
243 p_realt_secs++;
244 break;
245 ;;
246 case SIGVTALRM:
247 p_virtt_secs++;
248 break;
249 case SIGPROF:
250 p_proft_secs++;
251 break;
252 ;;
253 }
254}
255
256static void c1_sig_handler(int signo) {
257 printf("Signal handler child 1, signal %i\n", signo);
258 switch (signo) {
259 case SIGALRM:
260 c1_realt_secs++;
261 break;
262 ;;
263 case SIGVTALRM:
264 c1_virtt_secs++;
265 break;
266 case SIGPROF:
267 c1_proft_secs++;
268 break;
269 ;;
270 }
271}
272
273static void c2_sig_handler(int signo) {
274 printf("Signal handler child 2, signal %i\n", signo);
275 switch (signo) {
276 case SIGALRM:
277 c2_realt_secs++;
278 break;
279 ;;
280 case SIGVTALRM:
281 c2_virtt_secs++;
282 break;
283 case SIGPROF:
284 c2_proft_secs++;
285 break;
286 ;;
287 }
288}
289
290long unsigned int elapsed_usecs(long sec, long usec) {
291 return( sec * 1000 + usec);
292}
293
294long unsigned int delta_time(struct itimerval proft,
295 struct itimerval realt) {
296 long p_usec = proft.it_value.tv_usec;
297 long r_usec = proft.it_value.tv_usec;
298 if ( p_usec > r_usec )
299 return (p_usec - r_usec);
300 /* else */
301 return (p_usec - r_usec);
302}
303
304long unsigned int fibonacci(unsigned int n) {
305 if (n == 0)
306 return 0;
307 else if (n == 1 || n == 2)
308 return 1;
309 else
310 return(fibonacci(n-1) + fibonacci(n-2));
311}
312
Note: See TracBrowser for help on using the repository browser.