Пример #1
0
Файл: proc.c Проект: 8l/inferno
Proc*
newproc(void)
{
	Proc *p;

	lock(&procalloc);
	for(;;) {
		if(p = procalloc.free)
			break;

		unlock(&procalloc);
		resrcwait("no procs");
		lock(&procalloc);
	}
	procalloc.free = p->qnext;
	unlock(&procalloc);

	p->type = Unknown;
	p->state = Scheding;
	p->pri = PriNormal;
	p->psstate = "New";
	p->mach = 0;
	p->qnext = 0;
	p->fpstate = FPINIT;
	p->kp = 0;
	p->killed = 0;
	p->swipend = 0;
	p->mp = 0;
	p->movetime = 0;
	p->delaysched = 0;
	p->edf = nil;
	memset(&p->defenv, 0, sizeof(p->defenv));
	p->env = &p->defenv;
	p->dbgreg = 0;
	kstrdup(&p->env->user, "*nouser");
	p->env->errstr = p->env->errbuf0;
	p->env->syserrstr = p->env->errbuf1;

	p->pid = incref(&pidalloc);
	if(p->pid == 0)
		panic("pidalloc");
	if(p->kstack == 0)
		p->kstack = smalloc(KSTACK);
	addprog(p);

	return p;
}
Пример #2
0
Файл: ps.c Проект: npe9/harvey
Proc*
psalloc(void)
{
	Proc *p;

	lock(&procalloc);
	for(;;) {
		if(p = procalloc.free)
			break;

		unlock(&procalloc);
		resrcwait("no procs");
		lock(&procalloc);
	}
	procalloc.free = p->qnext;
	procalloc.nproc++;
	unlock(&procalloc);

	return p;
}
Пример #3
0
Proc*
newproc(void)
{
	char msg[64];
	Proc *p;

	lock(&procalloc);
	for(;;) {
		if((p = procalloc.free) != nil)
			break;

		snprint(msg, sizeof msg, "no procs; %s forking",
			up != nil ? up->text: "kernel");
		unlock(&procalloc);
		resrcwait(msg);
		lock(&procalloc);
	}
	procalloc.free = p->qnext;
	unlock(&procalloc);

	p->state = Scheding;
	p->psstate = "New";
	p->mach = nil;
	p->eql = nil;
	p->qnext = nil;
	p->nchild = 0;
	p->nwait = 0;
	p->waitq = nil;
	p->parent = nil;
	p->pgrp = nil;
	p->egrp = nil;
	p->fgrp = nil;
	p->rgrp = nil;
	p->pdbg = nil;
	p->fpstate = FPinit;
	p->kp = 0;
	p->procctl = 0;
	p->syscalltrace = nil;	
	p->notepending = 0;
	p->ureg = nil;
	p->privatemem = 0;
	p->noswap = 0;
	p->errstr = p->errbuf0;
	p->syserrstr = p->errbuf1;
	p->errbuf0[0] = '\0';
	p->errbuf1[0] = '\0';
	p->nlocks = 0;
	p->delaysched = 0;
	p->trace = 0;
	kstrdup(&p->user, "*nouser");
	kstrdup(&p->text, "*notext");
	kstrdup(&p->args, "");
	p->nargs = 0;
	p->setargs = 0;
	memset(p->seg, 0, sizeof p->seg);
	p->parentpid = 0;
	p->noteid = pidalloc(p);
	if(p->kstack == nil)
		p->kstack = smalloc(KSTACK);

	/* sched params */
	p->mp = nil;
	p->wired = nil;
	procpriority(p, PriNormal, 0);
	p->cpu = 0;
	p->lastupdate = MACHP(0)->ticks*Scaling;
	p->edf = nil;

	return p;
}
Пример #4
0
Image*
attachimage(int type, Chan *c, ulong base, ulong len)
{
	Image *i, **l;

	lock(&imagealloc);

	/*
	 * Search the image cache for remains of the text from a previous
	 * or currently running incarnation
	 */
	for(i = ihash(c->qid.path); i; i = i->hash) {
		if(c->qid.path == i->qid.path) {
			lock(i);
			if(eqqid(c->qid, i->qid) &&
			   eqqid(c->mqid, i->mqid) &&
			   c->mchan == i->mchan &&
			   c->type == i->type) {
				goto found;
			}
			unlock(i);
		}
	}

	/*
	 * imagereclaim dumps pages from the free list which are cached by image
	 * structures. This should free some image structures.
	 */
	while(!(i = imagealloc.free)) {
		unlock(&imagealloc);
		imagereclaim();
		if(!imagealloc.free){
			freebroken();		/* can use the memory */
			resrcwait("no image after reclaim");
		}
		lock(&imagealloc);
	}

	imagealloc.free = i->next;

	lock(i);
	incref(c);
	c->flag &= ~CCACHE;
	i->c = c;
	i->type = c->type;
	i->qid = c->qid;
	i->mqid = c->mqid;
	i->mchan = c->mchan;
	l = &ihash(c->qid.path);
	i->hash = *l;
	*l = i;
found:
	unlock(&imagealloc);

	if(i->s == 0) {
		i->ref++;
		if(waserror()) {
			unlock(i);
			putimage(i);
			nexterror();
		}
		i->s = newseg(type, base, len);
		i->s->image = i;
		poperror();
	}
	else
		incref(i->s);

	return i;
}
Пример #5
0
static long
sdrio(SDreq* r, void* a, long n)
{
	char *errstr;
	int rv;
	void *data;
	SDunit *u;
	int (*f)(SDreq*);

	if(n >= SDmaxio || n < 0)
		error(Etoobig);
	u = r->unit;
	if(u->haversense && r->cmd[0] == 0x03){
		u->haversense = 0;
		r->rlen = sizeof u->rsense;
		if(r->rlen > n)
			r->rlen = n;
		memmove(a, u->rsense, r->rlen);
		r->status = SDok;
		return r->rlen;
	}

	data = nil;
	while(n > 0 && (data = sdmalloc(n)) == nil){
		if(!waserror()){
			resrcwait("no memory for sdrio");
			poperror();
		}
	}
	if(waserror()){
		sdfree(data);
		r->data = nil;
		nexterror();
	}
	if(r->write && n > 0)
		memmove(data, a, n);
	r->data = data;
	r->dlen = n;

	if(r->proto == SData){
		f = u->dev->ifc->ataio;
		errstr = Enoata;
	}else{
		f = u->dev->ifc->rio;
		errstr = Enoscsi;
	}
	if(f == nil)
		error(errstr);
	rv = f(r);
	if(r->flags & SDvalidsense){
		memmove(u->rsense, r->sense, sizeof u->rsense);
		u->haversense = 1;
	}
	if(rv != SDok)
		error(Eio);

	if(!r->write && r->rlen > 0)
		memmove(a, data, r->rlen);
	poperror();
	sdfree(data);
	r->data = nil;

	return r->rlen;
}
Пример #6
0
static long
sdbio(Chan* c, int write, char* a, long len, uvlong off)
{
	int nchange, hard, allocd, locked;
	long l;
	uchar *b;
	SDpart *pp;
	SDunit *unit;
	SDev *sdev;
	ulong max, nb, offset;
	uvlong bno;

	sdev = sdgetdev(DEV(c->qid));
	if(sdev == nil){
		decref(&sdev->r);
		error(Enonexist);
	}
	unit = sdev->unit[UNIT(c->qid)];
	if(unit == nil)
		error(Enonexist);

	nchange = 0;
	qlock(&unit->ctl);
	while(waserror()){
		/* notification of media change; go around again */
		if(strcmp(up->errstr, Eio) == 0 && unit->sectors == 0 && nchange++ == 0){
			sdinitpart(unit);
			continue;
		}

		/* other errors; give up */
		qunlock(&unit->ctl);
		decref(&sdev->r);
		nexterror();
	}
	pp = &unit->part[PART(c->qid)];
	if(unit->vers+pp->vers != c->qid.vers)
		error(Echange);

	/*
	 * Check the request is within bounds.
	 * Removeable drives are locked throughout the I/O
	 * in case the media changes unexpectedly.
	 * Non-removeable drives are not locked during the I/O
	 * to allow the hardware to optimise if it can; this is
	 * a little fast and loose.
	 * It's assumed that non-removeable media parameters
	 * (sectors, secsize) can't change once the drive has
	 * been brought online.
	 */
	bno = (off/unit->secsize) + pp->start;
	nb = ((off+len+unit->secsize-1)/unit->secsize) + pp->start - bno;
	max = SDmaxio/unit->secsize;
	if(nb > max)
		nb = max;
	if(bno+nb > pp->end)
		nb = pp->end - bno;
	if(bno >= pp->end || nb == 0){
		if(write)
			error(Eio);
		qunlock(&unit->ctl);
		decref(&sdev->r);
		poperror();
		return 0;
	}
	locked = (unit->inquiry[1] & 0x80) != 0;
	if(!locked){
		qunlock(&unit->ctl);
		poperror();
	}

	offset = off%unit->secsize;
	if(offset+len > nb*unit->secsize)
		len = nb*unit->secsize - offset;
	hard = offset || write && len%unit->secsize;

	if(iskaddr(a) && ((uintptr)a & (BY2PG-1))==0 && !hard) {
		b = (uchar*)a;
		allocd = 0;
	}else{
		while((b = sdmalloc(nb*unit->secsize)) == nil){
			if(!waserror()){
				resrcwait("no memory for sdbio");
				poperror();
			}
		}
		allocd = 1;
	}
	if(waserror()){
		if(allocd)
			sdfree(b);
		if(!locked)
			decref(&sdev->r);		/* gadverdamme! */
		nexterror();
	}

	if(write){
		if(hard){
			l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
			if(l < 0)
				error(Eio);
			if(l < (nb*unit->secsize)){
				nb = l/unit->secsize;
				l = nb*unit->secsize - offset;
				if(len > l)
					len = l;
			}
		}
		if(allocd)
			memmove(b+offset, a, len);
		l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno);
		if(l < 0)
			error(Eio);
		if(l < offset)
			len = 0;
		else if(len > l - offset)
			len = l - offset;
	}
	else{
		l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
		if(l < 0)
			error(Eio);
		if(l < offset)
			len = 0;
		else if(len > l - offset)
			len = l - offset;
		if(allocd)
			memmove(a, b+offset, len);
	}
	if(allocd)
		sdfree(b);
	poperror();

	if(locked){
		qunlock(&unit->ctl);
		poperror();
	}

	decref(&sdev->r);
	return len;
}
Пример #7
0
Proc*
newproc(void)
{
	char msg[64];
	Proc *p;

	lock(&procalloc);
	while((p = procalloc.free) == nil) {
		unlock(&procalloc);

		snprint(msg, sizeof msg, "no procs; %s forking",
			up? up->text: "kernel");
		/*
		 * the situation is unlikely to heal itself.
		 * dump the proc table and restart by default.
		 * *noprocspersist in plan9.ini will yield the old
		 * behaviour of trying forever.
		 */
		if(getconf("*noprocspersist") == nil)
			noprocpanic(msg);
		resrcwait(msg);
		lock(&procalloc);
	}
	procalloc.free = p->qnext;
	unlock(&procalloc);

	p->state = Scheding;
	p->psstate = "New";
	p->mach = 0;
	p->qnext = 0;
	p->nchild = 0;
	p->nwait = 0;
	p->waitq = 0;
	p->parent = 0;
	p->pgrp = 0;
	p->egrp = 0;
	p->fgrp = 0;
	p->rgrp = 0;
	p->pdbg = 0;
	p->fpstate = FPinit;
	p->kp = 0;
	if(up && up->procctl == Proc_tracesyscall)
		p->procctl = Proc_tracesyscall;
	else
		p->procctl = 0;
	p->syscalltrace = 0;	
	p->notepending = 0;
	p->ureg = 0;
	p->privatemem = 0;
	p->noswap = 0;
	p->errstr = p->errbuf0;
	p->syserrstr = p->errbuf1;
	p->errbuf0[0] = '\0';
	p->errbuf1[0] = '\0';
	p->nlocks.ref = 0;
	p->delaysched = 0;
	p->trace = 0;
	kstrdup(&p->user, "*nouser");
	kstrdup(&p->text, "*notext");
	kstrdup(&p->args, "");
	p->nargs = 0;
	p->setargs = 0;
	memset(p->seg, 0, sizeof p->seg);
	p->pid = incref(&pidalloc);
	pidhash(p);
	p->noteid = incref(&noteidalloc);
	if(p->pid==0 || p->noteid==0)
		panic("pidalloc");
	if(p->kstack == 0)
		p->kstack = smalloc(KSTACK);

	/* sched params */
	p->mp = 0;
	p->wired = 0;
	procpriority(p, PriNormal, 0);
	p->cpu = 0;
	p->lastupdate = MACHP(0)->ticks*Scaling;
	p->edf = nil;

	return p;
}