root/kern/test/tt3.c

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

DEFINITIONS

This source file includes following definitions.
  1. setup
  2. sleepalot_thread
  3. waker_thread
  4. make_sleepalots
  5. compute_thread
  6. make_computes
  7. finish
  8. runtest3
  9. threadtest3

   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  * More thread test code.
  32  */
  33 #include <types.h>
  34 #include <lib.h>
  35 #include <wchan.h>
  36 #include <thread.h>
  37 #include <synch.h>
  38 #include <test.h>
  39 
  40 #include "opt-synchprobs.h"
  41 
  42 /* dimension of matrices (cannot be too large or will overflow stack) */
  43 
  44 #if OPT_SYNCHPROBS
  45 #define DIM 10
  46 #else
  47 #define DIM 70
  48 #endif
  49 
  50 /* number of iterations for sleepalot threads */
  51 #define SLEEPALOT_PRINTS      20        /* number of printouts */
  52 #define SLEEPALOT_ITERS       4         /* iterations per printout */
  53 /* polling frequency of waker thread */
  54 #define WAKER_WAKES          100
  55 /* number of iterations per compute thread */
  56 #define COMPUTE_ITERS         10
  57 
  58 #define NWAITCHANS 12
  59 static struct wchan *waitchans[NWAITCHANS];  /* N distinct wait channels */
  60 
  61 static volatile int wakerdone;
  62 static struct semaphore *wakersem;
  63 static struct semaphore *donesem;
  64 
  65 static
  66 void
  67 setup(void)
  68 {
  69         char tmp[16];
  70         int i;
  71 
  72         if (wakersem == NULL) {
  73                 wakersem = sem_create("wakersem", 1);
  74                 donesem = sem_create("donesem", 0);
  75                 for (i=0; i<NWAITCHANS; i++) {
  76                         snprintf(tmp, sizeof(tmp), "wc%d", i);
  77                         waitchans[i] = wchan_create(kstrdup(tmp));
  78                 }
  79         }
  80         wakerdone = 0;
  81 }
  82 
  83 static
  84 void
  85 sleepalot_thread(void *junk, unsigned long num)
  86 {
  87         int i, j;
  88 
  89         (void)junk;
  90 
  91         for (i=0; i<SLEEPALOT_PRINTS; i++) {
  92                 for (j=0; j<SLEEPALOT_ITERS; j++) {
  93                         struct wchan *w;
  94 
  95                         w = waitchans[random()%NWAITCHANS];
  96                         wchan_lock(w);
  97                         wchan_sleep(w);
  98                 }
  99                 kprintf("[%lu]", num);
 100         }
 101         V(donesem);
 102 }
 103 
 104 static
 105 void
 106 waker_thread(void *junk1, unsigned long junk2)
 107 {
 108         int i, done;
 109 
 110         (void)junk1;
 111         (void)junk2;
 112 
 113         while (1) {
 114                 P(wakersem);
 115                 done = wakerdone;
 116                 V(wakersem);
 117                 if (done) {
 118                         break;
 119                 }
 120 
 121                 for (i=0; i<WAKER_WAKES; i++) {
 122                         struct wchan *w;
 123 
 124                         w = waitchans[random()%NWAITCHANS];
 125                         wchan_wakeall(w);
 126 
 127                         thread_yield();
 128                 }
 129         }
 130         V(donesem);
 131 }
 132 
 133 static
 134 void
 135 make_sleepalots(int howmany)
 136 {
 137         char name[16];
 138         int i, result;
 139 
 140         for (i=0; i<howmany; i++) {
 141                 snprintf(name, sizeof(name), "sleepalot%d", i);
 142                 result = thread_fork(name, NULL, sleepalot_thread, NULL, i);
 143                 if (result) {
 144                         panic("thread_fork failed: %s\n", strerror(result));
 145                 }
 146         }
 147         result = thread_fork("waker", NULL, waker_thread, NULL, 0);
 148         if (result) {
 149                 panic("thread_fork failed: %s\n", strerror(result));
 150         }
 151 }
 152 
 153 static
 154 void
 155 compute_thread(void *junk1, unsigned long num)
 156 {
 157         struct matrix {
 158                 char m[DIM][DIM];
 159         };
 160         struct matrix *m1, *m2, *m3;
 161         unsigned char tot;
 162         int i, j, k, m;
 163         uint32_t rand;
 164 
 165         (void)junk1;
 166 
 167         m1 = kmalloc(sizeof(struct matrix));
 168         KASSERT(m1 != NULL);
 169         m2 = kmalloc(sizeof(struct matrix));
 170         KASSERT(m2 != NULL);
 171         m3 = kmalloc(sizeof(struct matrix));
 172         KASSERT(m3 != NULL);
 173 
 174         for (m=0; m<COMPUTE_ITERS; m++) {
 175 
 176                 for (i=0; i<DIM; i++) {
 177                         for (j=0; j<DIM; j++) {
 178                                 rand = random();
 179                                 m1->m[i][j] = rand >> 16;
 180                                 m2->m[i][j] = rand & 0xffff;
 181                         }
 182                 }
 183                 
 184                 for (i=0; i<DIM; i++) {
 185                         for (j=0; j<DIM; j++) {
 186                                 tot = 0;
 187                                 for (k=0; k<DIM; k++) {
 188                                         tot += m1->m[i][k] * m2->m[k][j];
 189                                 }
 190                                 m3->m[i][j] = tot;
 191                         }
 192                 }
 193                 
 194                 tot = 0;
 195                 for (i=0; i<DIM; i++) {
 196                         tot += m3->m[i][i];
 197                 }
 198 
 199                 kprintf("{%lu: %u}", num, (unsigned) tot);
 200                 thread_yield();
 201         }
 202 
 203         kfree(m1);
 204         kfree(m2);
 205         kfree(m3);
 206 
 207         V(donesem);
 208 }
 209 
 210 static
 211 void
 212 make_computes(int howmany)
 213 {
 214         char name[16];
 215         int i, result;
 216 
 217         for (i=0; i<howmany; i++) {
 218                 snprintf(name, sizeof(name), "compute%d", i);
 219                 result = thread_fork(name, NULL, compute_thread, NULL, i);
 220                 if (result) {
 221                         panic("thread_fork failed: %s\n", strerror(result));
 222                 }
 223         }
 224 }
 225 
 226 static
 227 void
 228 finish(int howmanytotal)
 229 {
 230         int i;
 231         for (i=0; i<howmanytotal; i++) {
 232                 P(donesem);
 233         }
 234         P(wakersem);
 235         wakerdone = 1;
 236         V(wakersem);
 237         P(donesem);
 238 }
 239 
 240 static
 241 void
 242 runtest3(int nsleeps, int ncomputes)
 243 {
 244         setup();
 245         kprintf("Starting thread test 3 (%d [sleepalots], %d {computes}, "
 246                 "1 waker)\n",
 247                 nsleeps, ncomputes);
 248         make_sleepalots(nsleeps);
 249         make_computes(ncomputes);
 250         finish(nsleeps+ncomputes);
 251         kprintf("\nThread test 3 done\n");
 252 }
 253 
 254 int
 255 threadtest3(int nargs, char **args)
 256 {
 257         if (nargs==1) {
 258                 runtest3(5, 2);
 259         }
 260         else if (nargs==3) {
 261                 runtest3(atoi(args[1]), atoi(args[2]));
 262         }
 263         else {
 264                 kprintf("Usage: tt3 [sleepthreads computethreads]\n");
 265                 return 1;
 266         }
 267         return 0;
 268 }

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