Exemple #1
0
/*
 *  called splhi() by notify().  See comment in notify for the
 *  reasoning.
 */
void
procctl(Proc *p)
{
	Mach *m = machp();
	Mpl pl;
	char *state;

	switch(p->procctl) {
	case Proc_exitbig:
		spllo();
		pexit("Killed: Insufficient physical memory", 1);

	case Proc_exitme:
		spllo();		/* pexit has locks in it */
		pexit("Killed", 1);

	case Proc_traceme:
		if(p->nnote == 0)
			return;
		/* No break */

	case Proc_stopme:
		p->procctl = 0;
		state = p->psstate;
		p->psstate = "Stopped";
		/* free a waiting debugger */
		pl = spllo();
		qlock(&p->debug);
		if(p->pdbg) {
			wakeup(&p->pdbg->sleep);
			p->pdbg = 0;
		}
		qunlock(&p->debug);
		splhi();
		p->state = Stopped;
		sched();
		p->psstate = state;
		splx(pl);
		return;

	case Proc_toac:
		p->procctl = 0;
		/*
		 * This pretends to return from the system call,
		 * by moving to a core, but never returns (unless
		 * the process gets moved back to a TC.)
		 */
		spllo();
		runacore();
		return;

	case Proc_totc:
		p->procctl = 0;
		if(p != m->externup)
			panic("procctl: stopac: p != up");
		spllo();
		stopac();
		return;
	}
}
Exemple #2
0
/*
 * 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();
}
Exemple #3
0
/*
 * 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();
}
Exemple #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);

	stopac();
	edfstop(up);
	p->state = Broken;
	p->psstate = 0;
	sched();
}
Exemple #5
0
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");
}