os161-1.99
 All Data Structures
uw-tests.c
00001 
00002 /*
00003  * UW - Synchronization test code.
00004  * Tim Brecht July, 2013
00005  * UW - uwvmstats tests code.
00006  * Tim Brecht January, 2014
00007  */
00008 
00009 #include <types.h>
00010 #include <synch.h>
00011 #include <thread.h>
00012 #include <test.h>
00013 #include <uw-vmstats.h>
00014 
00015 #define NAME_LEN (30)
00016 
00017 static struct lock *testlock = NULL;
00018 static struct semaphore *donesem = NULL;
00019 
00020 #define NTESTLOOPS    (5000)  /* Needs to be evenly divisible by 8 */
00021 #define NTESTTHREADS  (8)
00022 #define START_VALUE   (0)
00023 static volatile int test_value = START_VALUE;
00024 static int use_locks = 1;
00025 
00026 static
00027 void
00028 cleanitems(void)
00029 {
00030         kprintf("cleanitems: Destroying sems and locks\n");
00031         lock_destroy(testlock);
00032   testlock = NULL;
00033         sem_destroy(donesem);
00034   donesem = NULL;
00035   test_value = START_VALUE;
00036 }
00037 
00038 static
00039 void
00040 inititems(void)
00041 {
00042         if (testlock==NULL) {
00043                 testlock = lock_create("testlock");
00044                 if (testlock == NULL) {
00045                         panic("synchtest: lock_create failed\n");
00046                 }
00047         }
00048 
00049         if (donesem==NULL) {
00050                 donesem = sem_create("donesem", 0);
00051                 if (donesem == NULL) {
00052                         panic("synchtest: sem_create failed\n");
00053                 }
00054         }
00055 }
00056 
00057 /* This thread adds values to a global variable. */
00058 static
00059 void
00060 add_thread(void *junk, unsigned long num)
00061 {
00062         int i;
00063         (void) num;
00064         (void) junk;
00065 
00066         for (i=0; i<NTESTLOOPS; i++) {
00067                 if (use_locks) {
00068                         lock_acquire(testlock);
00069                 }
00070 
00071       /* This loop is unrolled to possibly avoid optimizations
00072        * and to provide more instructions that could be interrupted.
00073        * This may or may not be necessary.
00074        */
00075                   test_value = test_value + 1;
00076                   test_value = test_value + 1;
00077                   test_value = test_value + 1;
00078                   test_value = test_value + 1;
00079                   test_value = test_value + 1;
00080 
00081                 if (use_locks) {
00082                         lock_release(testlock);
00083                 }
00084 
00085         }
00086         V(donesem);
00087         thread_exit();
00088 }
00089 
00090 /* This thread substract values from a global variable. */
00091 static
00092 void
00093 sub_thread(void *junk, unsigned long num)
00094 {
00095         int i;
00096         (void)num;
00097         (void)junk;
00098 
00099         for (i=0; i<NTESTLOOPS; i++) {
00100                 if (use_locks) {
00101                         lock_acquire(testlock);
00102                 }
00103 
00104       /* This loop is unrolled to avoid optimizations
00105        * and to provide more instructions that could be interrupted.
00106        * This may or may not be necessary.
00107        */
00108                   test_value = test_value - 1;
00109                   test_value = test_value - 1;
00110                   test_value = test_value - 1;
00111                   test_value = test_value - 1;
00112                   test_value = test_value - 1;
00113 
00114                 if (use_locks) {
00115                         lock_release(testlock);
00116                 }
00117 
00118         }
00119         V(donesem);
00120         thread_exit();
00121 }
00122 
00123 int
00124 uwlocktest1(int nargs, char **args)
00125 {
00126         int i, result;
00127   char name[NAME_LEN];
00128 
00129         (void)nargs;
00130         (void)args;
00131 
00132         inititems();
00133         kprintf("Starting uwlocktest1...\n");
00134 
00135         for (i=0; i<NTESTTHREADS; i++) {
00136     snprintf(name, NAME_LEN, "add_thread %d", i);
00137                 result = thread_fork(name, NULL, add_thread, NULL, i);
00138                 if (result) {
00139                         panic("uwlocktest1: thread_fork failed: %s\n",
00140                               strerror(result));
00141                 }
00142         }
00143 
00144         for (i=0; i<NTESTTHREADS; i++) {
00145     snprintf(name, NAME_LEN, "sub_thread %d", i);
00146                 result = thread_fork(name, NULL, sub_thread, NULL, i);
00147                 if (result) {
00148                         panic("uwlocktest1: thread_fork failed: %s\n",
00149                               strerror(result));
00150                 }
00151         }
00152 
00153         for (i=0; i<NTESTTHREADS*2; i++) {
00154                 P(donesem);
00155         }
00156 
00157         kprintf("value of test_value = %d should be %d\n", test_value, START_VALUE);
00158         if (test_value == START_VALUE) {
00159         kprintf("TEST SUCCEEDED\n");
00160   } else {
00161         kprintf("TEST FAILED\n");
00162   }
00163         KASSERT(test_value == START_VALUE);
00164 
00165         cleanitems();
00166         kprintf("uwlocktest1 done.\n");
00167 
00168         return 0;
00169 }
00170 
00171 /*-----------------------------------------------------------------------*/
00172 
00173 /* Each thread makes some calls to vmstats functions */
00174 static
00175 void
00176 vmstats_thread(void *junk, unsigned long num)
00177 {
00178         int i;
00179         int j;
00180         (void)num;
00181         (void)junk;
00182 
00183         for (i=0; i<NTESTLOOPS; i++) {
00184     for (j=0; j<VMSTAT_COUNT; j++) {
00185         /* NOTE: The number of calls to vmstats_inc below have been manipulated
00186          * so the checks during printing add up properly and pass the various tests
00187          */
00188         switch(j) { 
00189           /* Need twice as many TLB faults */
00190           case VMSTAT_TLB_FAULT:
00191             vmstats_inc(j);
00192             vmstats_inc(j);
00193             break;
00194 
00195           case VMSTAT_TLB_FAULT_FREE:
00196             vmstats_inc(j);
00197             break;
00198 
00199           case VMSTAT_TLB_FAULT_REPLACE:
00200             vmstats_inc(j);
00201             break;
00202 
00203           /* Just reduce these to compare (not necessary) */
00204           case VMSTAT_TLB_INVALIDATE:
00205             if (i % 2 == 0) {
00206                vmstats_inc(j);
00207             }
00208             break;
00209 
00210           case VMSTAT_TLB_RELOAD:
00211             vmstats_inc(j);
00212             break;
00213 
00214           /* VMSTAT_TLB_FAULT = VMSTAT_TLB_RELOAD + VMSTAT_PAGE_FAULT_DISK + VMSTAT_SWAP_FILE_ZERO */
00215           case VMSTAT_PAGE_FAULT_ZERO:
00216             if (i % 2 == 0) {
00217                vmstats_inc(j);
00218             }
00219             break;
00220 
00221           /* VMSTAT_PAGE_FAULT_DISK = VMSTAT_ELF_FILE_READ + VMSTAT_SWAP_FILE_READ */
00222           case VMSTAT_PAGE_FAULT_DISK:
00223             if (i % 2 == 0) {
00224                vmstats_inc(j);
00225             }
00226             break;
00227 
00228           case VMSTAT_ELF_FILE_READ:
00229             if (i % 4 == 0) {
00230                vmstats_inc(j);
00231             }
00232             break;
00233 
00234           case VMSTAT_SWAP_FILE_READ:
00235             if (i % 4 == 0) {
00236                vmstats_inc(j);
00237             }
00238             break;
00239 
00240           case VMSTAT_SWAP_FILE_WRITE:
00241             if (i % 8 == 0) {
00242                vmstats_inc(j);
00243             }
00244             break;
00245 
00246           default:
00247             kprintf("Unknown stat %d\n", j);
00248             break;
00249       }
00250     }
00251         }
00252 
00253         V(donesem);
00254         thread_exit();
00255 }
00256 
00257 int
00258 uwvmstatstest(int nargs, char **args)
00259 {
00260         int i, result;
00261   char name[NAME_LEN];
00262 
00263         (void)nargs;
00264         (void)args;
00265 
00266         inititems();
00267         kprintf("Starting uwvmstatstest...\n");
00268 
00269   kprintf("Initializing vmstats\n");
00270   vmstats_init();
00271 
00272         for (i=0; i<NTESTTHREADS; i++) {
00273     snprintf(name, NAME_LEN, "vmstatsthread %d", i);
00274                 result = thread_fork(name, NULL, vmstats_thread, NULL, i);
00275                 if (result) {
00276                         panic("uwvmstatstest: thread_fork failed: %s\n",
00277                               strerror(result));
00278                 }
00279         }
00280 
00281         for (i=0; i<NTESTTHREADS; i++) {
00282                 P(donesem);
00283         }
00284 
00285   vmstats_print();
00286 
00287         cleanitems();
00288         kprintf("uwvmstatstest done.\n");
00289 
00290         return 0;
00291 }
00292 
00293 
 All Data Structures