diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
| commit | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch) | |
| tree | c6e220ba61db3a6ea4052e6841296d829654e664 /os/mpc/devbench.c | |
| parent | 46439007cf417cbd9ac8049bb4122c890097a0fa (diff) | |
20060303
Diffstat (limited to 'os/mpc/devbench.c')
| -rw-r--r-- | os/mpc/devbench.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/os/mpc/devbench.c b/os/mpc/devbench.c new file mode 100644 index 00000000..a35a57b0 --- /dev/null +++ b/os/mpc/devbench.c @@ -0,0 +1,243 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +typedef struct Psync Psync; + +enum { + Maxprocs=2, +}; + +struct Psync { + Rendez r; + int flag; +}; +static Psync timesync[Maxprocs]; +static Ref nactive; +static Ref nbusy; + +static int +timev(void *a) +{ + return *(int*)a; +} + +static void +timesched0(void *ap) +{ + long tot, t, i, lim, low, max; + Psync *ps; + + ps = ap; + sleep(&ps->r, timev, &ps->flag); + setpri(PriRealtime); + incref(&nbusy); + while(nbusy.ref < nactive.ref) + sched(); + lim = 1000; + low = 64000000; + max = 0; + tot = 0; + for(i=0; i<lim; i++){ +if(i<8)print("%lud\n", up->pid); + do{ + t = gettbl(); + sched(); + t = gettbl()-t; + }while(t < 0); + if(t < low) + low = t; + if(t > max) + max = t; + tot += t; + } + print("%lud %lud %lud %lud %lud\n", up->pid, lim, tot, low, max); + decref(&nactive); + pexit("", 0); +} + +static void +timesched(void) +{ + int i, np; + + for(np=1; np<=Maxprocs; np++){ + nactive.ref = np; + print("%d procs\n", np); + setpri(PriRealtime); + for(i=0; i<np; i++) + kproc("timesched", timesched0, ×ync[i], 0); + for(i=0; i<np; i++){ + timesync[i].flag = 1; + wakeup(×ync[i].r); + } + setpri(PriNormal); + while(nactive.ref>0) + sched(); + } +} + +typedef struct Ictr Ictr; +struct Ictr { + ulong base; + ulong sleep; + ulong spllo; + ulong intr; + ulong isave; + ulong arrive; + ulong wakeup; + ulong awake; +}; +static Ictr counters[100], *curct; +static int intrwant; +static Rendez vous; +int spltbl; /* set by spllo */ +int intrtbl; /* set by intrvec() */ +int isavetbl; /* set by intrvec() */ + +static void +intrwake(Ureg*, void*) +{ + m->iomem->tgcr &= ~1; /* reset the timer */ + curct->spllo = spltbl; + curct->intr = intrtbl; + curct->isave = isavetbl; + curct->arrive = gettbl(); + intrwant = 0; + wakeup(&vous); + curct->wakeup = gettbl(); +} + +/* + * sleep calls intrtest with splhi (under lock): + * provoke the interrupt now, so that it is guaranteed + * not to happen until sleep has queued the process, + * forcing wakeup to do something. + */ +static int +intrtest(void*) +{ + m->iomem->tgcr |= 1; /* enable timer: allow interrupt */ + curct->sleep = gettbl(); + return intrwant==0; +} + +static void +intrtime(void) +{ + IMM *io; + Ictr *ic; + long t; + int i; + + sched(); + curct = counters; + io = ioplock(); + io->tgcr &= ~3; + iopunlock(); + intrenable(VectorCPIC+0x19, intrwake, nil, BUSUNKNOWN, "bench"); + for(i=0; i<nelem(counters); i++){ + curct = &counters[i]; + //puttbl(0); + intrwant = 1; + io = m->iomem; /* don't lock, to save time */ + io->tmr1 = (0<<8)|TimerORI|TimerSclk; + io->trr1 = 1; + curct->base = gettbl(); + sleep(&vous, intrtest, nil); + curct->awake = gettbl(); + sched(); /* just to slow it down between trials */ + } + m->iomem->tmr1 = 0; + print("interrupt\n"); + for(i=0; i<20; i++){ + ic = &counters[i]; + t = ic->awake - ic->base; + ic->awake -= ic->wakeup; + ic->wakeup -= ic->arrive; + ic->arrive -= ic->isave; + ic->isave -= ic->intr; + ic->intr -= ic->spllo; + ic->spllo -= ic->sleep; + ic->sleep -= ic->base; + 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); + } +} + +static Chan* +benchattach(char *spec) +{ + timesched(); + intrtime(); + USED(spec); + error(Eperm); + return nil; +} + +static Walkqid* +benchwalk(Chan*, Chan*, char**, int) +{ + error(Enonexist); + return 0; +} + +static Chan* +benchopen(Chan*, int) +{ + error(Eperm); + return nil; +} + +static int +benchstat(Chan*, uchar*, int) +{ + error(Eperm); + return 0; +} + +static void +benchclose(Chan*) +{ +} + +static long +benchread(Chan *c, void *buf, long n, vlong offset) +{ + USED(c, buf, n, offset); + error(Eperm); + return 0; +} + +static long +benchwrite(Chan *c, void *buf, long n, vlong offset) +{ + USED(c, buf, n, offset); + error(Eperm); + return 0; +} + + +Dev benchdevtab = { + 'x', + "bench", + + devreset, + devinit, + devshutdown, + benchattach, + benchwalk, + benchstat, + benchopen, + devcreate, + benchclose, + benchread, + devbread, + benchwrite, + devbwrite, + devremove, + devwstat, +}; |
