M pc/devi82365.c => pc/devi82365.c +1 -1
@@ 294,7 294,7 @@ pcmmap(int slotno, ulong offset, int len, int attr)
}
m->isa = PADDR(umbmalloc(0, len, Mgran));
if(m->isa == 0){
- print("pcmmap: out of isa space\n");
+ print("pcmmap: %d out of isa space\n", len);
unlock(&pp->mlock);
return 0;
}
M port/devproc.c => port/devproc.c +15 -0
@@ 948,6 948,21 @@ procctlreq(Proc *p, char *va, int n)
if(i > p->basepri && !iseve())
error(Eperm);
p->basepri = i;
+ p->fixedpri = 0;
+ }
+ else
+ if(strncmp(buf, "fixedpri", 8) == 0) {
+ if(n < 9)
+ error(Ebadctl);
+ i = atoi(buf+9);
+ if(i < 0)
+ i = 0;
+ if(i >= Nrq)
+ i = Nrq - 1;
+ if(i > p->basepri && !iseve())
+ error(Eperm);
+ p->basepri = i;
+ p->fixedpri = 1;
}
else
if(strncmp(buf, "wired", 5) == 0) {
M port/portdat.h => port/portdat.h +2 -0
@@ 41,6 41,7 @@ typedef struct Session Session;
typedef struct Talarm Talarm;
typedef struct Target Target;
typedef struct Waitq Waitq;
+typedef struct Watchdog Watchdog;
typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
@@ 613,6 614,7 @@ struct Proc
Mach *mp; /* machine this process last ran on */
ulong priority; /* priority level */
ulong basepri; /* base priority level */
+ uchar fixedpri; /* priority level deson't change */
ulong rt; /* # ticks used since last blocked */
ulong art; /* avg # ticks used since last blocked */
ulong movetime; /* last time process switched processors */
M port/portfns.h => port/portfns.h +4 -0
@@ 323,6 323,10 @@ void* vmemchr(void*, int, int);
Proc* wakeup(Rendez*);
int walk(Chan**, char*, int);
int walkname(Chan**, char*, int);
+Watchdog* wdCreate(void);
+char* wdDelete(Watchdog*);
+char* wdStart(Watchdog*, ulong, void (*)(int), int);
+char* wdCancel(Watchdog*);
void wlock(RWlock*);
void wunlock(RWlock*);
void* xalloc(ulong);
M port/proc.c => port/proc.c +22 -18
@@ 146,26 146,30 @@ ready(Proc *p)
s = splhi();
- /* history counts */
- if(p->state == Running){
- p->rt++;
- pri = ((p->art + (p->rt<<1))>>2)/Squantum;
+ if(p->fixedpri){
+ pri = p->basepri;
} else {
- p->art = (p->art + (p->rt<<1))>>2;
- p->rt = 0;
- pri = p->art/Squantum;
- }
- pri = p->basepri - pri;
- if(pri < 0)
- pri = 0;
-
- /* the only intersection between the classes is at PriNormal */
- if(pri < PriNormal && p->basepri > PriNormal)
- pri = PriNormal;
+ /* history counts */
+ if(p->state == Running){
+ p->rt++;
+ pri = ((p->art + (p->rt<<1))>>2)/Squantum;
+ } else {
+ p->art = (p->art + (p->rt<<1))>>2;
+ p->rt = 0;
+ pri = p->art/Squantum;
+ }
+ pri = p->basepri - pri;
+ if(pri < 0)
+ pri = 0;
+
+ /* the only intersection between the classes is at PriNormal */
+ if(pri < PriNormal && p->basepri > PriNormal)
+ pri = PriNormal;
- /* stick at low priority any process waiting for a lock */
- if(p->lockwait)
- pri = PriLock;
+ /* stick at low priority any process waiting for a lock */
+ if(p->lockwait)
+ pri = PriLock;
+ }
p->priority = pri;
rq = &runq[p->priority];
M port/sysproc.c => port/sysproc.c +1 -0
@@ 187,6 187,7 @@ sysrfork(ulong *arg)
flushmmu();
p->priority = up->priority;
p->basepri = up->basepri;
+ p->fixedpri = up->fixedpri;
p->mp = up->mp;
wm = up->wired;
if(wm)
A port/watchdog.c => port/watchdog.c +136 -0
@@ 0,0 1,136 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#define WDMAGIC 0xfaceface
+
+struct Watchdog
+{
+ Watchdog *next;
+ ulong magic;
+ ulong ticks;
+ void (*f)(int);
+ ulong arg;
+ uchar armed;
+};
+
+struct {
+ Lock;
+ Watchdog *wd;
+} wdalloc;
+
+Watchdog*
+wdCreate(void)
+{
+ Watchdog *wd;
+
+ wd = mallocz(sizeof(Watchdog), 1);
+ if(wd == nil)
+ return nil;
+ wd->magic = WDMAGIC;
+ return wd;
+}
+
+static char*
+wdunlink(Watchdog *wd, ulong magic)
+{
+ char *rv;
+ Watchdog **l;
+
+ rv = "not started";
+ ilock(&wdalloc);
+ wd->magic = magic;
+ for(l = &wdalloc.wd; *l != nil; l = &(*l)->next)
+ if(*l == wd){
+ *l = wd->next;
+ rv = nil;
+ break;
+ }
+ wd->armed = 0;
+ iunlock(&wdalloc);
+ return rv;
+}
+
+char*
+wdDelete(Watchdog *wd)
+{
+ if(wd->magic != WDMAGIC)
+ return "not a watchdog";
+
+ wdunlink(wd, ~WDMAGIC);
+ free(wd);
+
+ return nil;
+}
+
+char*
+wdStart(Watchdog *wd, ulong ms, void (*f)(int), int arg)
+{
+ Watchdog **l;
+
+ if(wd->magic != WDMAGIC)
+ return "not a watchdog";
+
+ /* unchain it in case it already is chained */
+ if(wd->armed)
+ wdunlink(wd, WDMAGIC);
+
+ /* chain the watchdogs in time order */
+ ilock(&wdalloc);
+ wd->ticks = MS2TK(ms) + MACHP(0)->ticks;
+ wd->f = f;
+ wd->arg = arg;
+ wd->armed = 1;
+ for(l = &wdalloc.wd; *l != nil; l = &(*l)->next)
+ if(wd->ticks < (*l)->ticks)
+ break;
+ wd->next = *l;
+ *l = wd;
+ iunlock(&wdalloc);
+
+ return nil;
+}
+
+char*
+wdCancel(Watchdog *wd)
+{
+ if(wd->magic != WDMAGIC)
+ return "not a watchdog";
+ return wdunlink(wd, WDMAGIC);
+}
+
+static void
+wdclock(void)
+{
+ Watchdog *wd, **l;
+
+ /* find the barking dogs, remoe from the chain */
+ ilock(&wdalloc);
+ wd = wdalloc.wd;
+ for(l = &wdalloc.wd; *l != nil; l = &(*l)->next)
+ if(MACHP(0)->ticks - (*l)->ticks >= 0x10000000)
+ break;
+ if(l == &wdalloc.wd)
+ wd = nil;
+ else {
+ wdalloc.wd = *l;
+ *l = nil;
+ }
+ iunlock(&wdalloc);
+
+ /* let them run */
+ for(; wd != nil; wd = wd->next){
+ wd->ticks = 0;
+ wd->armed = 0;
+ (*wd->f)(wd->arg);
+ }
+}
+
+void
+watchdoglink(void)
+{
+ addclock0link(wdclock);
+}