1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <sys/wait.h> 6 #include <signal.h> 7 #include <math.h> 8 9 #define ROUNDS 20 10 #define SWAPS 40 11 int max_error = 5; 12 #include "common.h" 13 14 15 16 int pipefdc[2]; 17 int pipefdp[2]; 18 int subtest = 0; 19 int child_is_dead = 0; 20 21 void dead_child(int n); 22 void do_child(void); 23 void do_parent(void); 24 void do_calcs(void); 25 void err(int n); 26 void quit(void); 27 28 void err(int n) 29 { 30 e(n); 31 } 32 33 void do_calcs(void) 34 { 35 float a, b, c, d, e; 36 float foo, bar; 37 int i; 38 subtest = 3; 39 40 a = 1.1; 41 b = 2.2; 42 c = 3.3; 43 d = 4.4; 44 e = 5.5; 45 46 foo = a * b; /* 2.42 */ 47 bar = c * d; /* 14.52 */ 48 49 i = 0; 50 while(i < ROUNDS) { 51 foo += c; /* 5.72 */ 52 foo *= d; /* 25.168 */ 53 foo /= e; /* 4.5760 */ 54 bar -= a; /* 13.42 */ 55 bar *= b; /* 29.524 */ 56 bar /= e; /* 5.3680 */ 57 58 /* Undo */ 59 foo *= e; 60 foo /= d; 61 foo -= c; 62 63 bar *= e; 64 bar /= b; 65 bar += a; 66 67 i++; 68 } 69 70 if (fabs(foo - (a * b)) > 0.0001) err(1); 71 if (fabs(bar - (c * d)) > 0.0001) err(2); 72 } 73 74 void dead_child(int n) 75 { 76 int status; 77 subtest = 4; 78 79 (void) n; /* Avoid warning about unused parameter */ 80 81 if (wait(&status) == -1) err(1); 82 83 if (!WIFEXITED(status)) { 84 err(2); 85 quit(); 86 } else { 87 errct += WEXITSTATUS(status); 88 child_is_dead = 1; 89 } 90 } 91 92 void do_child(void) 93 { 94 char buf[2]; 95 int s; 96 97 s = 0; 98 close(pipefdp[0]); 99 close(pipefdc[1]); 100 101 while(s < SWAPS) { 102 do_calcs(); 103 104 /* Wake up parent */ 105 write(pipefdp[1], buf, 1); 106 107 /* Wait for parent to wake me up */ 108 read(pipefdc[0], buf, 1); 109 110 s++; 111 } 112 exit(0); 113 } 114 115 void do_parent(void) 116 { 117 int s; 118 char buf[2]; 119 struct sigaction sa; 120 subtest = 2; 121 122 sa.sa_handler = dead_child; 123 sa.sa_flags = 0; 124 if (sigaction(SIGCHLD, &sa, NULL) == -1) err(1); 125 126 s = 0; 127 close(pipefdp[1]); 128 close(pipefdc[0]); 129 130 while(s < SWAPS) { 131 /* Wait for child to wake me up */ 132 read(pipefdp[0], buf, 1); 133 134 do_calcs(); 135 136 /* Wake up child */ 137 write(pipefdc[1], buf, 1); 138 s++; 139 } 140 141 while(child_is_dead == 0) { fflush(stdout); } /* Busy wait */ 142 143 quit(); 144 } 145 146 int main(void) 147 { 148 pid_t r; 149 subtest = 1; 150 151 start(52); 152 153 if (pipe(pipefdc) == -1) err(1); 154 if (pipe(pipefdp) == -1) err(2); 155 156 r = fork(); 157 if(r < 0) { 158 err(3); 159 } else if(r == 0) { 160 /* Child */ 161 do_child(); 162 } else { 163 /* Parent */ 164 do_parent(); 165 } 166 167 return(0); /* Never reached */ 168 169 } 170 171