Exemple #1
0
void
tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms)
{
	if(up->tt != nil){
		print("tsleep: timer active: mode %d, tf %#p\n", up->tmode, up->tf);
		timerdel(up);
	}
	up->tns = MS2NS(ms);
	up->tf = twakeup;
	up->tmode = Trelative;
	up->ta = up;
	up->trend = r;
	up->tfn = fn;
	timeradd(up);

	if(waserror()){
		timerdel(up);
		nexterror();
	}
	sleep(r, tfn, arg);
	if(up->tt != nil)
		timerdel(up);
	up->twhen = 0;
	poperror();
}
Exemple #2
0
void
tsleep(Rendez *r, int (*fn)(void*), void *arg, int32_t ms)
{
	Mach *m = machp();
	if (m->externup->tt){
		print("tsleep: timer active: mode %d, tf %#p\n",
			m->externup->tmode, m->externup->tf);
		timerdel(m->externup);
	}
	m->externup->tns = MS2NS(ms);
	m->externup->tf = twakeup;
	m->externup->tmode = Trelative;
	m->externup->ta = m->externup;
	m->externup->trend = r;
	m->externup->tfn = fn;
	timeradd(m->externup);

	if(waserror()){
		timerdel(m->externup);
		nexterror();
	}
	sleep(r, tfn, arg);
	if (m->externup->tt)
		timerdel(m->externup);
	m->externup->twhen = 0;
	poperror();
}
Exemple #3
0
void
tsleep(Rendez *r, int (*fn)(void*), void *arg, int64_t ms)
{
	Proc *up = externup();
	if (up->Timer.tt){
		print("tsleep: timer active: mode %d, tf %#p\n",
			up->Timer.tmode, up->Timer.tf);
		timerdel(&up->Timer);
	}
	up->Timer.tns = MS2NS(ms);
	up->Timer.tf = twakeup;
	up->Timer.tmode = Trelative;
	up->Timer.ta = up;
	up->trend = r;
	up->tfn = fn;
	timeradd(&up->Timer);

	if(waserror()){
		timerdel(&up->Timer);
		nexterror();
	}
	sleep(r, tfn, arg);
	if (up->Timer.tt)
		timerdel(&up->Timer);
	up->Timer.twhen = 0;
	poperror();
}
Exemple #4
0
void
edfstop(Proc *p)
{
	Edf *e;

	if(e = edflock(p)){
		DPRINT("%lu edfstop %d[%s]\n", now, p->pid, statename[p->state]);
		if(p->trace)
			proctrace(p, SExpel, 0);
		e->flags &= ~Admitted;
		if(e->Timer.tt)
			timerdel(&e->Timer);
		edfunlock();
	}
}
Exemple #5
0
Fichier : edf.c Projet : 8l/inferno
void
edfstop(Proc *p)
{
	Edf *e;
	void (*pt)(Proc*, int, vlong);

	if (e = edflock(p)){
		DPRINT("%t edfstop %lud[%s]\n", now, p->pid, statename[p->state]);
		if(pt = proctrace)
			pt(p, SExpel, now);
		e->flags &= ~Admitted;
		if (e->tt)
			timerdel(e);
		edfunlock();
	}
}
Exemple #6
0
static void
setalarm(void)
{
	Proc *p;
	ulong now;
	
	now = msec();
	if(alarmtimer.tt)
		timerdel(&alarmtimer);
	while((p = alarms.head) && p->alarm == 0)
		alarms.head = p->palarm;
	if(p == nil)
		return;
	alarmtimer.tf = soundalarms;
	alarmtimer.tmode = Trelative;
	alarmtimer.tns = (p->alarm - now)*1000000LL;
	timeradd(&alarmtimer);
}
Exemple #7
0
/*
 * called with the Loop qlocked,
 * so only pushlink can mess with the queues
 */
static void
closelink(Link *link, int dofree)
{
	Queue *iq, *oq;
	Block *bp;

	ilock(link);
	iq = link->iq;
	oq = link->oq;
	bp = link->tq;
	link->tq = nil;
	link->tqtail = nil;
	link->tout = 0;
	link->tin = 0;
	timerdel(&link->ci);
	iunlock(link);
	if(iq != nil){
		qclose(iq);
		if(dofree){
			ilock(link);
			free(iq);
			link->iq = nil;
			iunlock(link);
		}
	}
	if(oq != nil){
		qclose(oq);
		if(dofree){
			ilock(link);
			free(oq);
			link->oq = nil;
			iunlock(link);
		}
	}
	freeblist(bp);
}
Exemple #8
0
/*
 * move blocks between queues if they are ready.
 * schedule an interrupt for the next interesting time.
 *
 * must be called with the link ilocked.
 */
static void
pushlink(Link *link, vlong now)
{
	Block *bp;
	vlong tout, tin;

	/*
	 * put another block in the link queue
	 */
	ilock(link);
	if(link->iq == nil || link->oq == nil){
		iunlock(link);
		return;

	}
	timerdel(&link->ci);

	/*
	 * put more blocks into the xmit queue
	 * use the time the last packet was supposed to go out
	 * as the start time for the next packet, rather than
	 * the current time.  this more closely models a network
	 * device which can queue multiple output packets.
	 */
	tout = link->tout;
	if(!tout)
		tout = now;
	while(tout <= now){
		bp = qget(link->oq);
		if(bp == nil){
			tout = 0;
			break;
		}

		/*
		 * can't send the packet before it gets queued
		 */
		tin = gtime(bp->rp);
		if(tin > tout)
			tout = tin;
		tout = tout + (BLEN(bp) - Tmsize) * link->delayn;

		/*
		 * drop packets
		 */
		if(link->droprate && nrand(link->droprate) == 0)
			link->drops++;
		else{
			ptime(bp->rp, tout + link->delay0ns);
			if(link->tq == nil)
				link->tq = bp;
			else
				link->tqtail->next = bp;
			link->tqtail = bp;
		}
	}

	/*
	 * record the next time a packet can be sent,
	 * but don't schedule an interrupt if none is waiting
	 */
	link->tout = tout;
	if(!qcanread(link->oq))
		tout = 0;

	/*
	 * put more blocks into the receive queue
	 */
	tin = 0;
	while(bp = link->tq){
		tin = gtime(bp->rp);
		if(tin > now)
			break;
		bp->rp += Tmsize;
		link->tq = bp->next;
		bp->next = nil;
		if(!link->indrop)
			qpassnolim(link->iq, bp);
		else if(qpass(link->iq, bp) < 0)
			link->soverflows++;
		tin = 0;
	}
	if(bp == nil && qisclosed(link->oq) && !qcanread(link->oq) && !qisclosed(link->iq))
		qhangup(link->iq, nil);
	link->tin = tin;
	if(!tin || tin > tout && tout)
		tin = tout;

	link->ci.ns = tin - now;
	if(tin){
		if(tin < now)
			panic("loopback unfinished business");
		timeradd(&link->ci);
	}
	iunlock(link);
}
Exemple #9
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");
}
Exemple #10
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");
}