Example #1
0
File: proc.c Project: Shamar/harvey
/*
 * Always splhi()'ed.
 */
void
schedinit(void)		/* never returns */
{
	Edf *e;

	machp()->inidle = 1;
	machp()->proc = nil;
	ainc(&run.nmach);

	setlabel(&machp()->sched);

	Proc *up = externup();

	if(infected_with_std()){
		print("mach %d got an std from %s (pid %d)!\n",
			machp()->machno,
			up ? up->text : "*notext",
			up ? up->pid : -1
		);
		disinfect_std();
	}

	if(up) {
		if((e = up->edf) && (e->flags & Admitted))
			edfrecord(up);
		machp()->qstart = 0;
		machp()->qexpired = 0;
		coherence();
		machp()->proc = 0;
		switch(up->state) {
		case Running:
			ready(up);
			break;
		case Moribund:
			up->state = Dead;
			stopac();
			edfstop(up);
			if (up->edf)
				free(up->edf);
			up->edf = nil;

			/*
			 * Holding locks from pexit:
			 * 	procalloc
			 *	pga
			 */
			mmurelease(up);
			unlock(&pga.l);

			psrelease(up);
			unlock(&procalloc.l);
			break;
		}
		up->mach = nil;
		updatecpu(up);
		machp()->externup = nil;
	}
	sched();
}
Example #2
0
File: proc.c Project: npe9/harvey
/*
 * Always splhi()'ed.
 */
void
schedinit(void)		/* never returns */
{
	Mach *m = machp();
	Edf *e;

	m->inidle = 1;
	m->proc = nil;
	ainc(&run.nmach);

	setlabel(&m->sched);
	if(m->externup) {
		if((e = m->externup->edf) && (e->flags & Admitted))
			edfrecord(m->externup);
		m->qstart = 0;
		m->qexpired = 0;
		coherence();
		m->proc = 0;
		switch(m->externup->state) {
		case Running:
			ready(m->externup);
			break;
		case Moribund:
			m->externup->state = Dead;
			stopac();
			edfstop(m->externup);
			if (m->externup->edf)
				free(m->externup->edf);
			m->externup->edf = nil;

			/*
			 * Holding locks from pexit:
			 * 	procalloc
			 *	pga
			 */
			mmurelease(m->externup);
			unlock(&pga);

			psrelease(m->externup);
			unlock(&procalloc);
			break;
		}
		m->externup->mach = nil;
		updatecpu(m->externup);
		m->externup = nil;
	}
	sched();
}
Example #3
0
/*
 * Always splhi()'ed.
 */
void
schedinit(void)		/* never returns */
{
	Edf *e;

	setlabel(&m->sched);
	if(up != nil) {
		if((e = up->edf) != nil && (e->flags & Admitted))
			edfrecord(up);
		m->proc = nil;
		switch(up->state) {
		case Running:
			ready(up);
			break;
		case Moribund:
			up->state = Dead;
			edfstop(up);
			if(up->edf != nil)
				free(up->edf);
			up->edf = nil;

			/*
			 * Holding locks from pexit:
			 * 	procalloc
			 *	palloc
			 */
			mmurelease(up);
			unlock(&palloc);

			up->mach = nil;
			updatecpu(up);

			up->qnext = procalloc.free;
			procalloc.free = up;

			/* proc is free now, make sure unlock() wont touch it */
			up = procalloc.Lock.p = nil;
			unlock(&procalloc);
			sched();
		}
		up->mach = nil;
		updatecpu(up);
		up = nil;
	}
	sched();
}
Example #4
0
void
addbroken(Proc *p)
{
	qlock(&broken);
	if(broken.n == NBROKEN) {
		ready(broken.p[0]);
		memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
		--broken.n;
	}
	broken.p[broken.n++] = p;
	qunlock(&broken);

	edfstop(up);
	p->state = Broken;
	p->psstate = nil;
	sched();
}
Example #5
0
File: proc.c Project: npe9/harvey
void
addbroken(Proc *p)
{
	Mach *m = machp();
	qlock(&broken);
	if(broken.n == NBROKEN) {
		ready(broken.p[0]);
		memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
		--broken.n;
	}
	broken.p[broken.n++] = p;
	qunlock(&broken);

	stopac();
	edfstop(m->externup);
	p->state = Broken;
	p->psstate = 0;
	sched();
}
Example #6
0
void
pexit(char *exitstr, int freemem)
{
	Proc *p;
	Segment **s, **es;
	long utime, stime;
	Waitq *wq;
	Fgrp *fgrp;
	Egrp *egrp;
	Rgrp *rgrp;
	Pgrp *pgrp;
	Chan *dot;
	void (*pt)(Proc*, int, vlong);

	up->alarm = 0;
	if(up->tt != nil)
		timerdel(up);
	pt = proctrace;
	if(pt != nil)
		pt(up, SDead, 0);

	/* nil out all the resources under lock (free later) */
	qlock(&up->debug);
	fgrp = up->fgrp;
	up->fgrp = nil;
	egrp = up->egrp;
	up->egrp = nil;
	rgrp = up->rgrp;
	up->rgrp = nil;
	pgrp = up->pgrp;
	up->pgrp = nil;
	dot = up->dot;
	up->dot = nil;
	qunlock(&up->debug);

	if(fgrp != nil)
		closefgrp(fgrp);
	if(egrp != nil)
		closeegrp(egrp);
	if(rgrp != nil)
		closergrp(rgrp);
	if(dot != nil)
		cclose(dot);
	if(pgrp != nil)
		closepgrp(pgrp);

	/*
	 * if not a kernel process and have a parent,
	 * do some housekeeping.
	 */
	if(up->kp == 0 && up->parentpid != 0) {
		wq = smalloc(sizeof(Waitq));
		wq->w.pid = up->pid;
		utime = up->time[TUser] + up->time[TCUser];
		stime = up->time[TSys] + up->time[TCSys];
		wq->w.time[TUser] = tk2ms(utime);
		wq->w.time[TSys] = tk2ms(stime);
		wq->w.time[TReal] = tk2ms(MACHP(0)->ticks - up->time[TReal]);
		if(exitstr != nil && exitstr[0])
			snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr);
		else
			wq->w.msg[0] = '\0';

		p = up->parent;
		lock(&p->exl);
		/*
		 * Check that parent is still alive.
		 */
		if(p->pid == up->parentpid && p->state != Broken) {
			p->nchild--;
			p->time[TCUser] += utime;
			p->time[TCSys] += stime;
			/*
			 * If there would be more than 128 wait records
			 * processes for my parent, then don't leave a wait
			 * record behind.  This helps prevent badly written
			 * daemon processes from accumulating lots of wait
			 * records.
		 	 */
			if(p->nwait < 128) {
				wq->next = p->waitq;
				p->waitq = wq;
				p->nwait++;
				wq = nil;
				wakeup(&p->waitr);
			}
		}
		unlock(&p->exl);
		if(wq != nil)
			free(wq);
	}
	else if(up->kp == 0 && up->parent == nil){
		if(exitstr == nil)
			exitstr = "unknown";
		panic("boot process died: %s", exitstr);
	}

	if(!freemem)
		addbroken(up);

	qlock(&up->seglock);
	es = &up->seg[NSEG];
	for(s = up->seg; s < es; s++) {
		if(*s != nil) {
			putseg(*s);
			*s = nil;
		}
	}
	qunlock(&up->seglock);

	lock(&up->exl);		/* Prevent my children from leaving waits */
	pidfree(up);
	up->pid = 0;
	wakeup(&up->waitr);
	unlock(&up->exl);

	while((wq = up->waitq) != nil){
		up->waitq = wq->next;
		free(wq);
	}

	/* release debuggers */
	qlock(&up->debug);
	if(up->pdbg != nil) {
		wakeup(&up->pdbg->sleep);
		up->pdbg = nil;
	}
	if(up->syscalltrace != nil) {
		free(up->syscalltrace);
		up->syscalltrace = nil;
	}
	qunlock(&up->debug);

	/* Sched must not loop for these locks */
	lock(&procalloc);
	lock(&palloc);

	edfstop(up);
	up->state = Moribund;
	sched();
	panic("pexit");
}
Example #7
0
File: proc.c Project: npe9/harvey
void
pexit(char *exitstr, int freemem)
{
	Mach *m = machp();
	Proc *p;
	Segment **s, **es;
	int32_t utime, stime;
	Waitq *wq, *f, *next;
	Fgrp *fgrp;
	Egrp *egrp;
	Rgrp *rgrp;
	Pgrp *pgrp;
	Chan *dot;

	if(0 && m->externup->nfullq > 0)
		iprint(" %s=%d", m->externup->text, m->externup->nfullq);
	if(0 && m->externup->nicc > 0)
		iprint(" [%s nicc %ud tctime %ulld actime %ulld]\n",
			m->externup->text, m->externup->nicc, m->externup->tctime, m->externup->actime);
	if(m->externup->syscalltrace != nil)
		free(m->externup->syscalltrace);
	m->externup->syscalltrace = nil;
	m->externup->alarm = 0;

	if (m->externup->tt)
		timerdel(m->externup);
	if(m->externup->trace)
		proctrace(m->externup, SDead, 0);

	/* nil out all the resources under lock (free later) */
	qlock(&m->externup->debug);
	fgrp = m->externup->fgrp;
	m->externup->fgrp = nil;
	egrp = m->externup->egrp;
	m->externup->egrp = nil;
	rgrp = m->externup->rgrp;
	m->externup->rgrp = nil;
	pgrp = m->externup->pgrp;
	m->externup->pgrp = nil;
	dot = m->externup->dot;
	m->externup->dot = nil;
	qunlock(&m->externup->debug);


	if(fgrp)
		closefgrp(fgrp);
	if(egrp)
		closeegrp(egrp);
	if(rgrp)
		closergrp(rgrp);
	if(dot)
		cclose(dot);
	if(pgrp)
		closepgrp(pgrp);

	/*
	 * if not a kernel process and have a parent,
	 * do some housekeeping.
	 */
	if(m->externup->kp == 0) {
		p = m->externup->parent;
		if(p == 0) {
			if(exitstr == 0)
				exitstr = "unknown";
			//die("bootprocessdeath");
			panic("boot process died: %s", exitstr);
		}

		while(waserror())
			;

		wq = smalloc(sizeof(Waitq));
		poperror();

		wq->w.pid = m->externup->pid;
		utime = m->externup->time[TUser] + m->externup->time[TCUser];
		stime = m->externup->time[TSys] + m->externup->time[TCSys];
		wq->w.time[TUser] = tk2ms(utime);
		wq->w.time[TSys] = tk2ms(stime);
		wq->w.time[TReal] = tk2ms(sys->machptr[0]->ticks - m->externup->time[TReal]);
		if(exitstr && exitstr[0])
			snprint(wq->w.msg, sizeof(wq->w.msg), "%s %d: %s",
				m->externup->text, m->externup->pid, exitstr);
		else
			wq->w.msg[0] = '\0';

		lock(&p->exl);
		/*
		 * Check that parent is still alive.
		 */
		if(p->pid == m->externup->parentpid && p->state != Broken) {
			p->nchild--;
			p->time[TCUser] += utime;
			p->time[TCSys] += stime;
			/*
			 * If there would be more than 128 wait records
			 * processes for my parent, then don't leave a wait
			 * record behind.  This helps prevent badly written
			 * daemon processes from accumulating lots of wait
			 * records.
		 	 */
			if(p->nwait < 128) {
				wq->next = p->waitq;
				p->waitq = wq;
				p->nwait++;
				wq = nil;
				wakeup(&p->waitr);
			}
		}
		unlock(&p->exl);
		if(wq)
			free(wq);
	}

	if(!freemem)
		addbroken(m->externup);

	qlock(&m->externup->seglock);
	es = &m->externup->seg[NSEG];
	for(s = m->externup->seg; s < es; s++) {
		if(*s) {
			putseg(*s);
			*s = 0;
		}
	}
	qunlock(&m->externup->seglock);

	lock(&m->externup->exl);		/* Prevent my children from leaving waits */
	psunhash(m->externup);
	m->externup->pid = 0;
	wakeup(&m->externup->waitr);
	unlock(&m->externup->exl);

	for(f = m->externup->waitq; f; f = next) {
		next = f->next;
		free(f);
	}

	/* release debuggers */
	qlock(&m->externup->debug);
	if(m->externup->pdbg) {
		wakeup(&m->externup->pdbg->sleep);
		m->externup->pdbg = 0;
	}
	qunlock(&m->externup->debug);

	/* Sched must not loop for these locks */
	lock(&procalloc);
	lock(&pga);

	stopac();
	edfstop(m->externup);
	m->externup->state = Moribund;
	sched();
	panic("pexit");
}