1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 #include "../port/error.h" 8 9 typedef struct Psync Psync; 10 11 enum { 12 Maxprocs=2, 13 }; 14 15 struct Psync { 16 Rendez r; 17 int flag; 18 }; 19 static Psync timesync[Maxprocs]; 20 static Ref nactive; 21 static Ref nbusy; 22 23 static int 24 timev(void *a) 25 { 26 return *(int*)a; 27 } 28 29 static void 30 timesched0(void *ap) 31 { 32 long tot, t, i, lim, low, max; 33 Psync *ps; 34 35 ps = ap; 36 sleep(&ps->r, timev, &ps->flag); 37 setpri(PriRealtime); 38 incref(&nbusy); 39 while(nbusy.ref < nactive.ref) 40 sched(); 41 lim = 1000; 42 low = 64000000; 43 max = 0; 44 tot = 0; 45 for(i=0; i<lim; i++){ 46 if(i<8)print("%lud\n", up->pid); 47 do{ 48 t = gettbl(); 49 sched(); 50 t = gettbl()-t; 51 }while(t < 0); 52 if(t < low) 53 low = t; 54 if(t > max) 55 max = t; 56 tot += t; 57 } 58 print("%lud %lud %lud %lud %lud\n", up->pid, lim, tot, low, max); 59 decref(&nactive); 60 pexit("", 0); 61 } 62 63 static void 64 timesched(void) 65 { 66 int i, np; 67 68 for(np=1; np<=Maxprocs; np++){ 69 nactive.ref = np; 70 print("%d procs\n", np); 71 setpri(PriRealtime); 72 for(i=0; i<np; i++) 73 kproc("timesched", timesched0, ×ync[i], 0); 74 for(i=0; i<np; i++){ 75 timesync[i].flag = 1; 76 wakeup(×ync[i].r); 77 } 78 setpri(PriNormal); 79 while(nactive.ref>0) 80 sched(); 81 } 82 } 83 84 typedef struct Ictr Ictr; 85 struct Ictr { 86 ulong base; 87 ulong sleep; 88 ulong spllo; 89 ulong intr; 90 ulong isave; 91 ulong arrive; 92 ulong wakeup; 93 ulong awake; 94 }; 95 static Ictr counters[100], *curct; 96 static int intrwant; 97 static Rendez vous; 98 int spltbl; /* set by spllo */ 99 int intrtbl; /* set by intrvec() */ 100 int isavetbl; /* set by intrvec() */ 101 102 static void 103 intrwake(Ureg*, void*) 104 { 105 m->iomem->tgcr &= ~1; /* reset the timer */ 106 curct->spllo = spltbl; 107 curct->intr = intrtbl; 108 curct->isave = isavetbl; 109 curct->arrive = gettbl(); 110 intrwant = 0; 111 wakeup(&vous); 112 curct->wakeup = gettbl(); 113 } 114 115 /* 116 * sleep calls intrtest with splhi (under lock): 117 * provoke the interrupt now, so that it is guaranteed 118 * not to happen until sleep has queued the process, 119 * forcing wakeup to do something. 120 */ 121 static int 122 intrtest(void*) 123 { 124 m->iomem->tgcr |= 1; /* enable timer: allow interrupt */ 125 curct->sleep = gettbl(); 126 return intrwant==0; 127 } 128 129 static void 130 intrtime(void) 131 { 132 IMM *io; 133 Ictr *ic; 134 long t; 135 int i; 136 137 sched(); 138 curct = counters; 139 io = ioplock(); 140 io->tgcr &= ~3; 141 iopunlock(); 142 intrenable(VectorCPIC+0x19, intrwake, nil, BUSUNKNOWN, "bench"); 143 for(i=0; i<nelem(counters); i++){ 144 curct = &counters[i]; 145 //puttbl(0); 146 intrwant = 1; 147 io = m->iomem; /* don't lock, to save time */ 148 io->tmr1 = (0<<8)|TimerORI|TimerSclk; 149 io->trr1 = 1; 150 curct->base = gettbl(); 151 sleep(&vous, intrtest, nil); 152 curct->awake = gettbl(); 153 sched(); /* just to slow it down between trials */ 154 } 155 m->iomem->tmr1 = 0; 156 print("interrupt\n"); 157 for(i=0; i<20; i++){ 158 ic = &counters[i]; 159 t = ic->awake - ic->base; 160 ic->awake -= ic->wakeup; 161 ic->wakeup -= ic->arrive; 162 ic->arrive -= ic->isave; 163 ic->isave -= ic->intr; 164 ic->intr -= ic->spllo; 165 ic->spllo -= ic->sleep; 166 ic->sleep -= ic->base; 167 print("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\n", ic->sleep, ic->spllo, ic->intr, ic->isave, ic->arrive, ic->wakeup, ic->awake, t); 168 } 169 } 170 171 static Chan* 172 benchattach(char *spec) 173 { 174 timesched(); 175 intrtime(); 176 USED(spec); 177 error(Eperm); 178 return nil; 179 } 180 181 static Walkqid* 182 benchwalk(Chan*, Chan*, char**, int) 183 { 184 error(Enonexist); 185 return 0; 186 } 187 188 static Chan* 189 benchopen(Chan*, int) 190 { 191 error(Eperm); 192 return nil; 193 } 194 195 static int 196 benchstat(Chan*, uchar*, int) 197 { 198 error(Eperm); 199 return 0; 200 } 201 202 static void 203 benchclose(Chan*) 204 { 205 } 206 207 static long 208 benchread(Chan *c, void *buf, long n, vlong offset) 209 { 210 USED(c, buf, n, offset); 211 error(Eperm); 212 return 0; 213 } 214 215 static long 216 benchwrite(Chan *c, void *buf, long n, vlong offset) 217 { 218 USED(c, buf, n, offset); 219 error(Eperm); 220 return 0; 221 } 222 223 224 Dev benchdevtab = { 225 'x', 226 "bench", 227 228 devreset, 229 devinit, 230 devshutdown, 231 benchattach, 232 benchwalk, 233 benchstat, 234 benchopen, 235 devcreate, 236 benchclose, 237 benchread, 238 devbread, 239 benchwrite, 240 devbwrite, 241 devremove, 242 devwstat, 243 }; 244