~kris/9p

9hist

4981fc0100c459a32cb9144f980972f15fb1fd2a — David du Colombier 25 years ago a9dcd3f
Plan 9 from Bell Labs 2001-03-15
7 files changed, 181 insertions(+), 19 deletions(-)

M pc/devi82365.c
M port/devproc.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M port/sysproc.c
A port/watchdog.c
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);
}