M alphapc/dat.h => alphapc/dat.h +1 -0
@@ 148,6 148,7 @@ struct Mach
ulong cpuhz; /* hwrpb->cfreq */
ulong pcclast;
uvlong fastclock;
+ vlong intrts; /* time stamp of last interrupt */
int pfault;
int cs;
M alphapc/trap.c => alphapc/trap.c +1 -0
@@ 41,6 41,7 @@ trap(Ureg *ur)
char buf[ERRLEN];
int user, x;
+ m->intrts = fastticks(nil);
user = ur->status&UMODE;
if(user){
M carrera/dat.h => carrera/dat.h +1 -0
@@ 117,6 117,7 @@ struct Mach
ulong fairness; /* for runproc */
ulong lastcyclecount;
uvlong fastclock;
+ vlong intrts; /* time stamp of last interrupt */
int flushmmu; /* make current proc flush it's mmu state */
int pfault;
M carrera/trap.c => carrera/trap.c +2 -0
@@ 196,6 196,8 @@ trap(Ureg *ur)
int user, cop, x, fpchk;
char buf[2*ERRLEN], buf1[ERRLEN], *fpexcep;
+ m->intrts = fastticks(nil);
+
/*
* Retry failed probes of legal addresses from tstbadvaddr
* workaround for the R4400 >2.3
M mpc/dat.h => mpc/dat.h +1 -0
@@ 140,6 140,7 @@ struct Mach
int load;
int intr;
vlong fastclock; /* last sampled value */
+ vlong intrts; /* time stamp of last interrupt */
int flushmmu; /* make current proc flush it's mmu state */
/* MUST BE LAST */
M mpc/trap.c => mpc/trap.c +1 -0
@@ 152,6 152,7 @@ trap(Ureg *ur)
int ecode;
static struct {int callsched;} c = {1};
+ m->intrts = fastticks(nil);
ecode = (ur->cause >> 8) & 0xff;
if(ecode < 0 || ecode >= 0x1F)
ecode = 0x1F;
M pc/dat.h => pc/dat.h +1 -0
@@ 171,6 171,7 @@ struct Mach
int load;
int intr;
vlong fastclock; /* last sampled value */
+ vlong intrts; /* time stamp of last interrupt */
int flushmmu; /* make current proc flush it's mmu state */
ulong spuriousintr;
M pc/fns.h => pc/fns.h +0 -1
@@ 95,7 95,6 @@ void procsetup(Proc*);
void putcr3(ulong);
void putcr4(ulong);
void rdmsr(int, vlong*);
-long readintrts(void*, int);
void screeninit(void);
int screenprint(char*, ...); /* debugging */
void (*screenputs)(char*, int);
M pc/trap.c => pc/trap.c +1 -4
@@ 15,9 15,6 @@ static void fault386(Ureg*, void*);
static Lock vctllock;
static Vctl *vctl[256];
-/* interrupt timestamps, l.s fills intrts each interupt */
-uvlong intrts;
-
void
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
{
@@ 175,6 172,7 @@ trap(Ureg* ureg)
Vctl *ctl, *v;
Mach *mach;
+ m->intrts = fastticks(nil);
user = 0;
if((ureg->cs & 0xFFFF) == UESEL){
user = 1;
@@ 375,7 373,6 @@ fault386(Ureg* ureg, void*)
read = !(ureg->ecode & 2);
insyscall = up->insyscall;
up->insyscall = 1;
- spllo();
n = fault(addr, read);
if(n < 0){
if(!user){
A port/devintrts.c => port/devintrts.c +134 -0
@@ 0,0 1,134 @@
+/*
+ */
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+enum {
+ Qdir,
+ Qintrts,
+};
+
+static Dirtab intrtsdir[] = {
+ "intrts", { Qintrts, 0 }, 0, 0666,
+};
+
+void (*saveintrts)(void) = nil;
+
+/* interrupt timestamps, trap() fills intrts each interrupt */
+uvlong intrts;
+static struct {
+ Lock;
+ int vno; /* vector to save timestamps for */
+ int n; /* number of valid timestamps in ts[] */
+ uvlong ts[128]; /* time stamps */
+} tsalloc;
+
+/* called with interrupts off by interrupt routine */
+void
+_saveintrts(void)
+{
+ lock(&tsalloc);
+ if(tsalloc.n < nelem(tsalloc.ts))
+ tsalloc.ts[tsalloc.n++] = m->intrts;
+ unlock(&tsalloc);
+}
+
+/* read interrupt timestamps */
+static long
+readintrts(void *buf, int n)
+{
+ n /= sizeof(uvlong);
+ if(n <= 0)
+ return 0;
+ ilock(&tsalloc);
+ if(n > tsalloc.n)
+ n = tsalloc.n;
+ memmove(buf, tsalloc.ts, n*sizeof(uvlong));
+ tsalloc.n = 0;
+ iunlock(&tsalloc);
+ return n*sizeof(uvlong);
+}
+
+
+static void
+intrtsreset(void)
+{
+ saveintrts = _saveintrts;
+}
+
+static Chan*
+intrtsattach(char* spec)
+{
+ return devattach('Z', spec); /* everything good was taken */
+}
+
+int
+intrtswalk(Chan* c, char* name)
+{
+ return devwalk(c, name, intrtsdir, nelem(intrtsdir), devgen);
+}
+
+static void
+intrtsstat(Chan* c, char* dp)
+{
+ devstat(c, dp, intrtsdir, nelem(intrtsdir), devgen);
+}
+
+static Chan*
+intrtsopen(Chan* c, int omode)
+{
+ return devopen(c, omode, intrtsdir, nelem(intrtsdir), devgen);
+}
+
+static void
+intrtsclose(Chan*)
+{
+}
+
+static long
+intrtsread(Chan* c, void* a, long n, vlong)
+{
+ switch(c->qid.path & ~CHDIR){
+
+ case Qdir:
+ return devdirread(c, a, n, intrtsdir, nelem(intrtsdir), devgen);
+
+ case Qintrts:
+ return readintrts(a, n);
+ }
+
+ error(Eperm);
+ return 0;
+}
+
+static long
+intrtswrite(Chan*, void*, long, vlong)
+{
+ error(Eperm);
+ return 0;
+}
+
+Dev intrtsdevtab = {
+ 'Z',
+ "intrts",
+
+ intrtsreset,
+ devinit,
+ intrtsattach,
+ devclone,
+ intrtswalk,
+ intrtsstat,
+ intrtsopen,
+ devcreate,
+ intrtsclose,
+ intrtsread,
+ devbread,
+ intrtswrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};
M port/devns16552.c => port/devns16552.c +2 -37
@@ 149,41 149,6 @@ struct Uartalloc {
void ns16552intr(int);
-/* interrupt timestamps, l.s fills intrts each interupt */
-uvlong intrts;
-static struct {
- Lock;
- int vno; /* vector to save timestamps for */
- int n; /* number of valid timestamps in ts[] */
- uvlong ts[128]; /* time stamps */
-} tsalloc;
-
-/* called with interrupts off by interrupt routine */
-static void
-savets(void)
-{
- lock(&tsalloc);
- if(tsalloc.n < nelem(tsalloc.ts))
- tsalloc.ts[tsalloc.n++] = intrts;
- unlock(&tsalloc);
-}
-
-/* read interrupt timestamps */
-long
-readintrts(void *buf, int n)
-{
- n /= sizeof(uvlong);
- if(n <= 0)
- return 0;
- ilock(&tsalloc);
- if(n > tsalloc.n)
- n = tsalloc.n;
- memmove(buf, tsalloc.ts, n*sizeof(uvlong));
- tsalloc.n = 0;
- iunlock(&tsalloc);
- return n*sizeof(uvlong);
-}
-
/*
* pick up architecture specific routines and definitions
*/
@@ 713,8 678,8 @@ ns16552intr(int dev)
}
if (ch & Dcdc) {
l = ch & Dcd;
- if(l == 0 && p->dcd != 0 && p->dcdts)
- savets();
+ if(l == 0 && p->dcd != 0 && p->dcdts && saveintrts != nil)
+ (*saveintrts)();
if(p->hup_dcd && p->dcd && !l){
ilock(&p->rlock);
p->dohup = 1;
M port/portfns.h => port/portfns.h +1 -0
@@ 266,6 266,7 @@ long rtctime(void);
void runlock(RWlock*);
Proc* runproc(void);
void savefpregs(FPsave*);
+void (*saveintrts)(void);
void sched(void);
void scheddump(void);
void schedinit(void);