root/kern/test/uw-tests.c

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

DEFINITIONS

This source file includes following definitions.
  1. cleanitems
  2. inititems
  3. add_thread
  4. sub_thread
  5. uwlocktest1
  6. vmstats_thread
  7. uwvmstatstest

   1 
   2 /*
   3  * UW - Synchronization test code.
   4  * Tim Brecht July, 2013
   5  * UW - uwvmstats tests code.
   6  * Tim Brecht January, 2014
   7  */
   8 
   9 #include <types.h>
  10 #include <synch.h>
  11 #include <thread.h>
  12 #include <test.h>
  13 #include <uw-vmstats.h>
  14 
  15 #define NAME_LEN (30)
  16 
  17 static struct lock *testlock = NULL;
  18 static struct semaphore *donesem = NULL;
  19 
  20 #define NTESTLOOPS    (5000)  /* Needs to be evenly divisible by 8 */
  21 #define NTESTTHREADS  (8)
  22 #define START_VALUE   (0)
  23 static volatile int test_value = START_VALUE;
  24 static int use_locks = 1;
  25 
  26 static
  27 void
  28 cleanitems(void)
  29 {
  30         kprintf("cleanitems: Destroying sems and locks\n");
  31         lock_destroy(testlock);
  32   testlock = NULL;
  33         sem_destroy(donesem);
  34   donesem = NULL;
  35   test_value = START_VALUE;
  36 }
  37 
  38 static
  39 void
  40 inititems(void)
  41 {
  42         if (testlock==NULL) {
  43                 testlock = lock_create("testlock");
  44                 if (testlock == NULL) {
  45                         panic("synchtest: lock_create failed\n");
  46                 }
  47         }
  48 
  49         if (donesem==NULL) {
  50                 donesem = sem_create("donesem", 0);
  51                 if (donesem == NULL) {
  52                         panic("synchtest: sem_create failed\n");
  53                 }
  54         }
  55 }
  56 
  57 /* This thread adds values to a global variable. */
  58 static
  59 void
  60 add_thread(void *junk, unsigned long num)
  61 {
  62         int i;
  63         (void) num;
  64         (void) junk;
  65 
  66         for (i=0; i<NTESTLOOPS; i++) {
  67                 if (use_locks) {
  68                         lock_acquire(testlock);
  69                 }
  70 
  71       /* This loop is unrolled to possibly avoid optimizations
  72        * and to provide more instructions that could be interrupted.
  73        * This may or may not be necessary.
  74        */
  75                   test_value = test_value + 1;
  76                   test_value = test_value + 1;
  77                   test_value = test_value + 1;
  78                   test_value = test_value + 1;
  79                   test_value = test_value + 1;
  80 
  81                 if (use_locks) {
  82                         lock_release(testlock);
  83                 }
  84 
  85         }
  86         V(donesem);
  87         thread_exit();
  88 }
  89 
  90 /* This thread substract values from a global variable. */
  91 static
  92 void
  93 sub_thread(void *junk, unsigned long num)
  94 {
  95         int i;
  96         (void)num;
  97         (void)junk;
  98 
  99         for (i=0; i<NTESTLOOPS; i++) {
 100                 if (use_locks) {
 101                         lock_acquire(testlock);
 102                 }
 103 
 104       /* This loop is unrolled to avoid optimizations
 105        * and to provide more instructions that could be interrupted.
 106        * This may or may not be necessary.
 107        */
 108                   test_value = test_value - 1;
 109                   test_value = test_value - 1;
 110                   test_value = test_value - 1;
 111                   test_value = test_value - 1;
 112                   test_value = test_value - 1;
 113 
 114                 if (use_locks) {
 115                         lock_release(testlock);
 116                 }
 117 
 118         }
 119         V(donesem);
 120         thread_exit();
 121 }
 122 
 123 int
 124 uwlocktest1(int nargs, char **args)
 125 {
 126         int i, result;
 127   char name[NAME_LEN];
 128 
 129         (void)nargs;
 130         (void)args;
 131 
 132         inititems();
 133         kprintf("Starting uwlocktest1...\n");
 134 
 135         for (i=0; i<NTESTTHREADS; i++) {
 136     snprintf(name, NAME_LEN, "add_thread %d", i);
 137                 result = thread_fork(name, NULL, add_thread, NULL, i);
 138                 if (result) {
 139                         panic("uwlocktest1: thread_fork failed: %s\n",
 140                               strerror(result));
 141                 }
 142         }
 143 
 144         for (i=0; i<NTESTTHREADS; i++) {
 145     snprintf(name, NAME_LEN, "sub_thread %d", i);
 146                 result = thread_fork(name, NULL, sub_thread, NULL, i);
 147                 if (result) {
 148                         panic("uwlocktest1: thread_fork failed: %s\n",
 149                               strerror(result));
 150                 }
 151         }
 152 
 153         for (i=0; i<NTESTTHREADS*2; i++) {
 154                 P(donesem);
 155         }
 156 
 157         kprintf("value of test_value = %d should be %d\n", test_value, START_VALUE);
 158         if (test_value == START_VALUE) {
 159         kprintf("TEST SUCCEEDED\n");
 160   } else {
 161         kprintf("TEST FAILED\n");
 162   }
 163         KASSERT(test_value == START_VALUE);
 164 
 165         cleanitems();
 166         kprintf("uwlocktest1 done.\n");
 167 
 168         return 0;
 169 }
 170 
 171 /*-----------------------------------------------------------------------*/
 172 
 173 /* Each thread makes some calls to vmstats functions */
 174 static
 175 void
 176 vmstats_thread(void *junk, unsigned long num)
 177 {
 178         int i;
 179         int j;
 180         (void)num;
 181         (void)junk;
 182 
 183         for (i=0; i<NTESTLOOPS; i++) {
 184     for (j=0; j<VMSTAT_COUNT; j++) {
 185         /* NOTE: The number of calls to vmstats_inc below have been manipulated
 186          * so the checks during printing add up properly and pass the various tests
 187          */
 188         switch(j) { 
 189           /* Need twice as many TLB faults */
 190           case VMSTAT_TLB_FAULT:
 191             vmstats_inc(j);
 192             vmstats_inc(j);
 193             break;
 194 
 195           case VMSTAT_TLB_FAULT_FREE:
 196             vmstats_inc(j);
 197             break;
 198 
 199           case VMSTAT_TLB_FAULT_REPLACE:
 200             vmstats_inc(j);
 201             break;
 202 
 203           /* Just reduce these to compare (not necessary) */
 204           case VMSTAT_TLB_INVALIDATE:
 205             if (i % 2 == 0) {
 206                vmstats_inc(j);
 207             }
 208             break;
 209 
 210           case VMSTAT_TLB_RELOAD:
 211             vmstats_inc(j);
 212             break;
 213 
 214           /* VMSTAT_TLB_FAULT = VMSTAT_TLB_RELOAD + VMSTAT_PAGE_FAULT_DISK + VMSTAT_SWAP_FILE_ZERO */
 215           case VMSTAT_PAGE_FAULT_ZERO:
 216             if (i % 2 == 0) {
 217                vmstats_inc(j);
 218             }
 219             break;
 220 
 221           /* VMSTAT_PAGE_FAULT_DISK = VMSTAT_ELF_FILE_READ + VMSTAT_SWAP_FILE_READ */
 222           case VMSTAT_PAGE_FAULT_DISK:
 223             if (i % 2 == 0) {
 224                vmstats_inc(j);
 225             }
 226             break;
 227 
 228           case VMSTAT_ELF_FILE_READ:
 229             if (i % 4 == 0) {
 230                vmstats_inc(j);
 231             }
 232             break;
 233 
 234           case VMSTAT_SWAP_FILE_READ:
 235             if (i % 4 == 0) {
 236                vmstats_inc(j);
 237             }
 238             break;
 239 
 240           case VMSTAT_SWAP_FILE_WRITE:
 241             if (i % 8 == 0) {
 242                vmstats_inc(j);
 243             }
 244             break;
 245 
 246           default:
 247             kprintf("Unknown stat %d\n", j);
 248             break;
 249       }
 250     }
 251         }
 252 
 253         V(donesem);
 254         thread_exit();
 255 }
 256 
 257 int
 258 uwvmstatstest(int nargs, char **args)
 259 {
 260         int i, result;
 261   char name[NAME_LEN];
 262 
 263         (void)nargs;
 264         (void)args;
 265 
 266         inititems();
 267         kprintf("Starting uwvmstatstest...\n");
 268 
 269   kprintf("Initializing vmstats\n");
 270   vmstats_init();
 271 
 272         for (i=0; i<NTESTTHREADS; i++) {
 273     snprintf(name, NAME_LEN, "vmstatsthread %d", i);
 274                 result = thread_fork(name, NULL, vmstats_thread, NULL, i);
 275                 if (result) {
 276                         panic("uwvmstatstest: thread_fork failed: %s\n",
 277                               strerror(result));
 278                 }
 279         }
 280 
 281         for (i=0; i<NTESTTHREADS; i++) {
 282                 P(donesem);
 283         }
 284 
 285   vmstats_print();
 286 
 287         cleanitems();
 288         kprintf("uwvmstatstest done.\n");
 289 
 290         return 0;
 291 }
 292 
 293 

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