From 4981fc0100c459a32cb9144f980972f15fb1fd2a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 15 Mar 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-03-15 --- pc/devi82365.c | 2 +- port/devproc.c | 15 ++++++ port/portdat.h | 2 + port/portfns.h | 4 ++ port/proc.c | 40 +++++++------- port/sysproc.c | 1 + port/watchdog.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 181 insertions(+), 19 deletions(-) create mode 100644 port/watchdog.c diff --git a/pc/devi82365.c b/pc/devi82365.c index 3fe515536bf05adaddf59696fc879cdde77337c8..2d08091849fac8c57df880c4a947d18516ec2aab 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -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; } diff --git a/port/devproc.c b/port/devproc.c index 5422f71247f38dcebd8fa0fde0bff1a2bb27b3ef..ff0fe91a0687aae05646fe73222bdf699821f6cf 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -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) { diff --git a/port/portdat.h b/port/portdat.h index 4d007c2336a8790ca2778afb03e7f84db2518928..eeba31aec8eed3d6c59850df08de2fb285cb5f3c 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -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 */ diff --git a/port/portfns.h b/port/portfns.h index d74f7175dc776c6d68723708bd7da124b90e5421..15e770f6a7f8d05e32ad8a8f6259a4176c402518 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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); diff --git a/port/proc.c b/port/proc.c index ebb8e429c6a54e8100a7491ece01f44c1060da1f..906fe0feb65b53c5ab85079317b3887fed029b95 100644 --- a/port/proc.c +++ b/port/proc.c @@ -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]; diff --git a/port/sysproc.c b/port/sysproc.c index 4dc60186198b824622f9aa56bb9c119f2f095827..db255d84bfdf5dd0a5bfd5dfce84524b4f036d6f 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -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) diff --git a/port/watchdog.c b/port/watchdog.c new file mode 100644 index 0000000000000000000000000000000000000000..27327d64a6c528e7fefe4d5b5a4e3ad282f190c8 --- /dev/null +++ b/port/watchdog.c @@ -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); +}