00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <sys/types.h>
00040 #include <sys/wait.h>
00041 #include <stdarg.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <stdlib.h>
00045 #include <unistd.h>
00046 #include <err.h>
00047
00048 #define NJOBS 24
00049
00050 #define DIM 35
00051 #define NMATS 11
00052 #define JOBSIZE ((NMATS+1)*DIM*DIM*sizeof(int))
00053
00054 static const int right_answers[NJOBS] = {
00055 -1337312809,
00056 356204544,
00057 -537881911,
00058 -65406976,
00059 1952063315,
00060 -843894784,
00061 1597000869,
00062 -993925120,
00063 838840559,
00064 -1616928768,
00065 -182386335,
00066 -364554240,
00067 251084843,
00068 -61403136,
00069 295326333,
00070 1488013312,
00071 1901440647,
00072 0,
00073 -1901440647,
00074 -1488013312,
00075 -295326333,
00076 61403136,
00077 -251084843,
00078 364554240,
00079 };
00080
00081
00082
00083 struct matrix {
00084 int m_data[DIM][DIM];
00085 };
00086
00087
00088
00089
00090
00091
00092
00093 static
00094 void
00095 say(const char *fmt, ...)
00096 {
00097 char buf[256];
00098 va_list ap;
00099 va_start(ap, fmt);
00100 vsnprintf(buf, sizeof(buf), fmt, ap);
00101 va_end(ap);
00102 write(STDOUT_FILENO, buf, strlen(buf));
00103 }
00104
00105
00106
00107 static
00108 void
00109 multiply(struct matrix *res, const struct matrix *m1, const struct matrix *m2)
00110 {
00111 int i, j, k;
00112
00113 for (i=0; i<DIM; i++) {
00114 for (j=0; j<DIM; j++) {
00115 int val=0;
00116 for (k=0; k<DIM; k++) {
00117 val += m1->m_data[i][k]*m2->m_data[k][j];
00118 }
00119 res->m_data[i][j] = val;
00120 }
00121 }
00122 }
00123
00124 static
00125 void
00126 addeq(struct matrix *m1, const struct matrix *m2)
00127 {
00128 int i, j;
00129 for (i=0; i<DIM; i++) {
00130 for (j=0; j<DIM; j++) {
00131 m1->m_data[i][j] += m2->m_data[i][j];
00132 }
00133 }
00134 }
00135
00136 static
00137 int
00138 trace(const struct matrix *m1)
00139 {
00140 int i, t=0;
00141 for (i=0; i<DIM; i++) {
00142 t += m1->m_data[i][i];
00143 }
00144 return t;
00145 }
00146
00147
00148
00149 static struct matrix mats[NMATS];
00150
00151 static
00152 void
00153 populate_initial_matrixes(int mynum)
00154 {
00155 int i,j;
00156 struct matrix *m = &mats[0];
00157 for (i=0; i<DIM; i++) {
00158 for (j=0; j<DIM; j++) {
00159 m->m_data[i][j] = mynum+i-2*j;
00160 }
00161 }
00162
00163 multiply(&mats[1], &mats[0], &mats[0]);
00164 }
00165
00166 static
00167 void
00168 compute(int n)
00169 {
00170 struct matrix tmp;
00171 int i, j;
00172
00173 for (i=0,j=n-1; i<j; i++,j--) {
00174 multiply(&tmp, &mats[i], &mats[j]);
00175 addeq(&mats[n], &tmp);
00176 }
00177 }
00178
00179 static
00180 void
00181 computeall(int mynum)
00182 {
00183 int i;
00184 populate_initial_matrixes(mynum);
00185 for (i=2; i<NMATS; i++) {
00186 compute(i);
00187 }
00188 }
00189
00190 static
00191 int
00192 answer(void)
00193 {
00194 return trace(&mats[NMATS-1]);
00195 }
00196
00197 static
00198 void
00199 go(int mynum)
00200 {
00201 int r;
00202
00203 say("Process %d (pid %d) starting computation...\n", mynum,
00204 (int) getpid());
00205
00206 computeall(mynum);
00207 r = answer();
00208
00209 if (r != right_answers[mynum]) {
00210 say("Process %d answer %d: FAILED, should be %d\n",
00211 mynum, r, right_answers[mynum]);
00212 exit(1);
00213 }
00214 say("Process %d answer %d: passed\n", mynum, r);
00215 exit(0);
00216 }
00217
00218
00219
00220 static
00221 int
00222 status_is_failure(int status)
00223 {
00224
00225 if (WIFSIGNALED(status)) {
00226 return 1;
00227 }
00228 if (!WIFEXITED(status)) {
00229
00230 return 1;
00231 }
00232 status = WEXITSTATUS(status);
00233 return status != 0;
00234 }
00235
00236 static
00237 void
00238 makeprocs(void)
00239 {
00240 int i, status, failcount;
00241 pid_t pids[NJOBS];
00242
00243 printf("Job size approximately %lu bytes\n", (unsigned long) JOBSIZE);
00244 printf("Forking %d jobs; total load %luk\n", NJOBS,
00245 (unsigned long) (NJOBS * JOBSIZE)/1024);
00246
00247 for (i=0; i<NJOBS; i++) {
00248 pids[i] = fork();
00249 if (pids[i]<0) {
00250 warn("fork");
00251 }
00252 if (pids[i]==0) {
00253
00254 go(i);
00255 }
00256 }
00257
00258 failcount=0;
00259 for (i=0; i<NJOBS; i++) {
00260 if (pids[i]<0) {
00261 failcount++;
00262 }
00263 else {
00264 if (waitpid(pids[i], &status, 0)<0) {
00265 err(1, "waitpid");
00266 }
00267 if (status_is_failure(status)) {
00268 failcount++;
00269 }
00270 }
00271 }
00272
00273 if (failcount>0) {
00274 printf("%d subprocesses failed\n", failcount);
00275 exit(1);
00276 }
00277 printf("Test complete\n");
00278 }
00279
00280 int
00281 main()
00282 {
00283 makeprocs();
00284 return 0;
00285 }