root/user/testbin/parallelvm/parallelvm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. say
  2. multiply
  3. addeq
  4. trace
  5. populate_initial_matrixes
  6. compute
  7. computeall
  8. answer
  9. go
  10. status_is_failure
  11. makeprocs
  12. main

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * parallelvm.c: highly parallelized VM stress test.
  32  *
  33  * This test probably won't run with only 512k of physical memory
  34  * (unless maybe if you have a *really* gonzo VM system) because each
  35  * of its processes needs to allocate a kernel stack, and those add up
  36  * quickly.
  37  */
  38 
  39 #include <sys/types.h>
  40 #include <sys/wait.h>
  41 #include <stdarg.h>
  42 #include <stdio.h>
  43 #include <string.h>
  44 #include <stdlib.h>
  45 #include <unistd.h>
  46 #include <err.h>
  47 
  48 #define NJOBS    24
  49 
  50 #define DIM      35
  51 #define NMATS    11
  52 #define JOBSIZE  ((NMATS+1)*DIM*DIM*sizeof(int))
  53 
  54 static const int right_answers[NJOBS] = {
  55         -1337312809,
  56         356204544,
  57         -537881911,
  58         -65406976,
  59         1952063315,
  60         -843894784,
  61         1597000869,
  62         -993925120,
  63         838840559,
  64         -1616928768,
  65         -182386335,
  66         -364554240,
  67         251084843,
  68         -61403136,
  69         295326333,
  70         1488013312,
  71         1901440647,
  72         0,
  73         -1901440647,
  74         -1488013312,
  75         -295326333,
  76         61403136,
  77         -251084843,
  78         364554240,
  79 };
  80 
  81 ////////////////////////////////////////////////////////////
  82 
  83 struct matrix {
  84         int m_data[DIM][DIM];
  85 };
  86 
  87 ////////////////////////////////////////////////////////////
  88 
  89 /*
  90  * Use this instead of just calling printf so we know each printout
  91  * is atomic; this prevents the lines from getting intermingled.
  92  */
  93 static
  94 void
  95 say(const char *fmt, ...)
  96 {
  97         char buf[256];
  98         va_list ap;
  99         va_start(ap, fmt);
 100         vsnprintf(buf, sizeof(buf), fmt, ap);
 101         va_end(ap);
 102         write(STDOUT_FILENO, buf, strlen(buf));
 103 }
 104 
 105 ////////////////////////////////////////////////////////////
 106 
 107 static
 108 void
 109 multiply(struct matrix *res, const struct matrix *m1, const struct matrix *m2)
 110 {
 111         int i, j, k;
 112 
 113         for (i=0; i<DIM; i++) {
 114                 for (j=0; j<DIM; j++) {
 115                         int val=0;
 116                         for (k=0; k<DIM; k++) {
 117                                 val += m1->m_data[i][k]*m2->m_data[k][j];
 118                         }
 119                         res->m_data[i][j] = val;
 120                 }
 121         }
 122 }
 123 
 124 static
 125 void
 126 addeq(struct matrix *m1, const struct matrix *m2)
 127 {
 128         int i, j;
 129         for (i=0; i<DIM; i++) {
 130                 for (j=0; j<DIM; j++) {
 131                         m1->m_data[i][j] += m2->m_data[i][j];
 132                 }
 133         }
 134 }
 135 
 136 static
 137 int
 138 trace(const struct matrix *m1)
 139 {
 140         int i, t=0;
 141         for (i=0; i<DIM; i++) {
 142                 t += m1->m_data[i][i];
 143         }
 144         return t;
 145 }
 146 
 147 ////////////////////////////////////////////////////////////
 148 
 149 static struct matrix mats[NMATS];
 150 
 151 static
 152 void
 153 populate_initial_matrixes(int mynum)
 154 {
 155         int i,j;
 156         struct matrix *m = &mats[0];
 157         for (i=0; i<DIM; i++) {
 158                 for (j=0; j<DIM; j++) {
 159                         m->m_data[i][j] = mynum+i-2*j;
 160                 }
 161         }
 162         
 163         multiply(&mats[1], &mats[0], &mats[0]);
 164 }
 165 
 166 static
 167 void
 168 compute(int n)
 169 {
 170         struct matrix tmp;
 171         int i, j;
 172 
 173         for (i=0,j=n-1; i<j; i++,j--) {
 174                 multiply(&tmp, &mats[i], &mats[j]);
 175                 addeq(&mats[n], &tmp);
 176         }
 177 }
 178 
 179 static
 180 void
 181 computeall(int mynum)
 182 {
 183         int i;
 184         populate_initial_matrixes(mynum);
 185         for (i=2; i<NMATS; i++) {
 186                 compute(i);
 187         }
 188 }
 189 
 190 static
 191 int
 192 answer(void)
 193 {
 194         return trace(&mats[NMATS-1]);
 195 }
 196 
 197 static
 198 void
 199 go(int mynum)
 200 {
 201         int r;
 202 
 203         say("Process %d (pid %d) starting computation...\n", mynum, 
 204             (int) getpid());
 205 
 206         computeall(mynum);
 207         r = answer();
 208 
 209         if (r != right_answers[mynum]) {
 210                 say("Process %d answer %d: FAILED, should be %d\n", 
 211                     mynum, r, right_answers[mynum]);
 212                 exit(1);
 213         }
 214         say("Process %d answer %d: passed\n", mynum, r);
 215         exit(0);
 216 }
 217 
 218 ////////////////////////////////////////////////////////////
 219 
 220 static
 221 int
 222 status_is_failure(int status)
 223 {
 224         /* Proper interpretation of Unix exit status */
 225         if (WIFSIGNALED(status)) {
 226                 return 1;
 227         }
 228         if (!WIFEXITED(status)) {
 229                 /* ? */
 230                 return 1;
 231         }
 232         status = WEXITSTATUS(status);
 233         return status != 0;
 234 }
 235 
 236 static
 237 void
 238 makeprocs(void)
 239 {
 240         int i, status, failcount;
 241         pid_t pids[NJOBS];
 242 
 243         printf("Job size approximately %lu bytes\n", (unsigned long) JOBSIZE);
 244         printf("Forking %d jobs; total load %luk\n", NJOBS,
 245                (unsigned long) (NJOBS * JOBSIZE)/1024);
 246 
 247         for (i=0; i<NJOBS; i++) {
 248                 pids[i] = fork();
 249                 if (pids[i]<0) {
 250                         warn("fork");
 251                 }
 252                 if (pids[i]==0) {
 253                         /* child */
 254                         go(i);
 255                 }
 256         }
 257 
 258         failcount=0;
 259         for (i=0; i<NJOBS; i++) {
 260                 if (pids[i]<0) {
 261                         failcount++;
 262                 }
 263                 else {
 264                         if (waitpid(pids[i], &status, 0)<0) {
 265                                 err(1, "waitpid");
 266                         }
 267                         if (status_is_failure(status)) {
 268                                 failcount++;
 269                         }
 270                 }
 271         }
 272 
 273         if (failcount>0) {
 274                 printf("%d subprocesses failed\n", failcount);
 275                 exit(1);
 276         }
 277         printf("Test complete\n");
 278 }
 279 
 280 int
 281 main()
 282 {
 283         makeprocs();
 284         return 0;
 285 }

/* [<][>][^][v][top][bottom][index][help] */