xref: /csrg-svn/sys/kern/kern_synch.c (revision 49095)
123376Smckusick /*
2*49095Skarels  * Copyright (c) 1982, 1986, 1990, 1991 Regents of the University of California.
323376Smckusick  * All rights reserved.  The Berkeley software License Agreement
423376Smckusick  * specifies the terms and conditions for redistribution.
523376Smckusick  *
6*49095Skarels  *	@(#)kern_synch.c	7.15 (Berkeley) 05/04/91
723376Smckusick  */
833Sbill 
917093Sbloom #include "param.h"
1017093Sbloom #include "systm.h"
1117093Sbloom #include "proc.h"
1217093Sbloom #include "kernel.h"
1317093Sbloom #include "buf.h"
14*49095Skarels #include "signalvar.h"
15*49095Skarels #include "resourcevar.h"
169756Ssam 
1747544Skarels #include "machine/cpu.h"
1845742Smckusick 
198102Sroot /*
208102Sroot  * Force switch among equal priority processes every 100ms.
218102Sroot  */
228102Sroot roundrobin()
238102Sroot {
248102Sroot 
2547544Skarels 	need_resched();
268624Sroot 	timeout(roundrobin, (caddr_t)0, hz / 10);
278102Sroot }
288102Sroot 
2932908Smckusick /*
3032908Smckusick  * constants for digital decay and forget
3132908Smckusick  *	90% of (p_cpu) usage in 5*loadav time
3232908Smckusick  *	95% of (p_pctcpu) usage in 60 seconds (load insensitive)
3332908Smckusick  *          Note that, as ps(1) mentions, this can let percentages
3432908Smckusick  *          total over 100% (I've seen 137.9% for 3 processes).
3532908Smckusick  *
3632908Smckusick  * Note that hardclock updates p_cpu and p_cpticks independently.
3732908Smckusick  *
3832908Smckusick  * We wish to decay away 90% of p_cpu in (5 * loadavg) seconds.
3932908Smckusick  * That is, the system wants to compute a value of decay such
4032908Smckusick  * that the following for loop:
4132908Smckusick  * 	for (i = 0; i < (5 * loadavg); i++)
4232908Smckusick  * 		p_cpu *= decay;
4332908Smckusick  * will compute
4432908Smckusick  * 	p_cpu *= 0.1;
4532908Smckusick  * for all values of loadavg:
4632908Smckusick  *
4732908Smckusick  * Mathematically this loop can be expressed by saying:
4832908Smckusick  * 	decay ** (5 * loadavg) ~= .1
4932908Smckusick  *
5032908Smckusick  * The system computes decay as:
5132908Smckusick  * 	decay = (2 * loadavg) / (2 * loadavg + 1)
5232908Smckusick  *
5332908Smckusick  * We wish to prove that the system's computation of decay
5432908Smckusick  * will always fulfill the equation:
5532908Smckusick  * 	decay ** (5 * loadavg) ~= .1
5632908Smckusick  *
5732908Smckusick  * If we compute b as:
5832908Smckusick  * 	b = 2 * loadavg
5932908Smckusick  * then
6032908Smckusick  * 	decay = b / (b + 1)
6132908Smckusick  *
6232908Smckusick  * We now need to prove two things:
6332908Smckusick  *	1) Given factor ** (5 * loadavg) ~= .1, prove factor == b/(b+1)
6432908Smckusick  *	2) Given b/(b+1) ** power ~= .1, prove power == (5 * loadavg)
6532908Smckusick  *
6632908Smckusick  * Facts:
6732908Smckusick  *         For x close to zero, exp(x) =~ 1 + x, since
6832908Smckusick  *              exp(x) = 0! + x**1/1! + x**2/2! + ... .
6932908Smckusick  *              therefore exp(-1/b) =~ 1 - (1/b) = (b-1)/b.
7032908Smckusick  *         For x close to zero, ln(1+x) =~ x, since
7132908Smckusick  *              ln(1+x) = x - x**2/2 + x**3/3 - ...     -1 < x < 1
7232908Smckusick  *              therefore ln(b/(b+1)) = ln(1 - 1/(b+1)) =~ -1/(b+1).
7332908Smckusick  *         ln(.1) =~ -2.30
7432908Smckusick  *
7532908Smckusick  * Proof of (1):
7632908Smckusick  *    Solve (factor)**(power) =~ .1 given power (5*loadav):
7732908Smckusick  *	solving for factor,
7832908Smckusick  *      ln(factor) =~ (-2.30/5*loadav), or
7947544Skarels  *      factor =~ exp(-1/((5/2.30)*loadav)) =~ exp(-1/(2*loadav)) =
8032908Smckusick  *          exp(-1/b) =~ (b-1)/b =~ b/(b+1).                    QED
8132908Smckusick  *
8232908Smckusick  * Proof of (2):
8332908Smckusick  *    Solve (factor)**(power) =~ .1 given factor == (b/(b+1)):
8432908Smckusick  *	solving for power,
8532908Smckusick  *      power*ln(b/(b+1)) =~ -2.30, or
8632908Smckusick  *      power =~ 2.3 * (b + 1) = 4.6*loadav + 2.3 =~ 5*loadav.  QED
8732908Smckusick  *
8832908Smckusick  * Actual power values for the implemented algorithm are as follows:
8932908Smckusick  *      loadav: 1       2       3       4
9032908Smckusick  *      power:  5.68    10.32   14.94   19.55
9132908Smckusick  */
9217541Skarels 
9338164Smckusick /* calculations for digital decay to forget 90% of usage in 5*loadav sec */
9447544Skarels #define	loadfactor(loadav)	(2 * (loadav))
9547544Skarels #define	decay_cpu(loadfac, cpu)	(((loadfac) * (cpu)) / ((loadfac) + FSCALE))
968102Sroot 
9738164Smckusick /* decay 95% of `p_pctcpu' in 60 seconds; see CCPU_SHIFT before changing */
9838164Smckusick fixpt_t	ccpu = 0.95122942450071400909 * FSCALE;		/* exp(-1/20) */
9938164Smckusick 
1008102Sroot /*
10138164Smckusick  * If `ccpu' is not equal to `exp(-1/20)' and you still want to use the
10238164Smckusick  * faster/more-accurate formula, you'll have to estimate CCPU_SHIFT below
10338164Smckusick  * and possibly adjust FSHIFT in "param.h" so that (FSHIFT >= CCPU_SHIFT).
10438164Smckusick  *
10538164Smckusick  * To estimate CCPU_SHIFT for exp(-1/20), the following formula was used:
10638164Smckusick  *	1 - exp(-1/20) ~= 0.0487 ~= 0.0488 == 1 (fixed pt, *11* bits).
10738164Smckusick  *
10838164Smckusick  * If you dont want to bother with the faster/more-accurate formula, you
10938164Smckusick  * can set CCPU_SHIFT to (FSHIFT + 1) which will use a slower/less-accurate
11038164Smckusick  * (more general) method of calculating the %age of CPU used by a process.
11138164Smckusick  */
11238164Smckusick #define	CCPU_SHIFT	11
11338164Smckusick 
11438164Smckusick /*
1158102Sroot  * Recompute process priorities, once a second
1168102Sroot  */
1178102Sroot schedcpu()
1188102Sroot {
11947544Skarels 	register fixpt_t loadfac = loadfactor(averunnable[0]);
1208102Sroot 	register struct proc *p;
12147544Skarels 	register int s;
12247544Skarels 	register unsigned int newcpu;
1238102Sroot 
1248102Sroot 	wakeup((caddr_t)&lbolt);
12516532Skarels 	for (p = allproc; p != NULL; p = p->p_nxt) {
12647544Skarels 		/*
12747544Skarels 		 * Increment time in/out of memory and sleep time
12847544Skarels 		 * (if sleeping).  We ignore overflow; with 16-bit int's
12947544Skarels 		 * (remember them?) overflow takes 45 days.
13047544Skarels 		 */
13147544Skarels 		p->p_time++;
13247544Skarels 		if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
13347544Skarels 			p->p_slptime++;
13438164Smckusick 		p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
13517541Skarels 		/*
13617541Skarels 		 * If the process has slept the entire second,
13717541Skarels 		 * stop recalculating its priority until it wakes up.
13817541Skarels 		 */
13938164Smckusick 		if (p->p_slptime > 1)
14017541Skarels 			continue;
14117541Skarels 		/*
14217541Skarels 		 * p_pctcpu is only for ps.
14317541Skarels 		 */
14438164Smckusick #if	(FSHIFT >= CCPU_SHIFT)
14538164Smckusick 		p->p_pctcpu += (hz == 100)?
14638164Smckusick 			((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT):
14738164Smckusick                 	100 * (((fixpt_t) p->p_cpticks)
14838164Smckusick 				<< (FSHIFT - CCPU_SHIFT)) / hz;
14938164Smckusick #else
15038164Smckusick 		p->p_pctcpu += ((FSCALE - ccpu) *
15138164Smckusick 			(p->p_cpticks * FSCALE / hz)) >> FSHIFT;
15238164Smckusick #endif
1538102Sroot 		p->p_cpticks = 0;
15447544Skarels 		newcpu = (u_int) decay_cpu(loadfac, p->p_cpu) + p->p_nice;
15547544Skarels 		p->p_cpu = min(newcpu, UCHAR_MAX);
15647544Skarels 		setpri(p);
15717541Skarels 		s = splhigh();	/* prevent state changes */
1588102Sroot 		if (p->p_pri >= PUSER) {
15947544Skarels #define	PPQ	(128 / NQS)		/* priorities per queue */
160*49095Skarels 			if ((p != curproc) &&
1618102Sroot 			    p->p_stat == SRUN &&
1628102Sroot 			    (p->p_flag & SLOAD) &&
16316795Skarels 			    (p->p_pri / PPQ) != (p->p_usrpri / PPQ)) {
1648102Sroot 				remrq(p);
1658102Sroot 				p->p_pri = p->p_usrpri;
1668102Sroot 				setrq(p);
1678102Sroot 			} else
1688102Sroot 				p->p_pri = p->p_usrpri;
1698102Sroot 		}
1708102Sroot 		splx(s);
1718102Sroot 	}
1728102Sroot 	vmmeter();
1738102Sroot 	if (bclnlist != NULL)
17447544Skarels 		wakeup((caddr_t)pageproc);
1758624Sroot 	timeout(schedcpu, (caddr_t)0, hz);
1768102Sroot }
1778102Sroot 
17817541Skarels /*
17917541Skarels  * Recalculate the priority of a process after it has slept for a while.
18047544Skarels  * For all load averages >= 1 and max p_cpu of 255, sleeping for at least
18147544Skarels  * six times the loadfactor will decay p_cpu to zero.
18217541Skarels  */
18317541Skarels updatepri(p)
18417541Skarels 	register struct proc *p;
18517541Skarels {
18647544Skarels 	register unsigned int newcpu = p->p_cpu;
18747544Skarels 	register fixpt_t loadfac = loadfactor(averunnable[0]);
18817541Skarels 
18947544Skarels 	if (p->p_slptime > 5 * loadfac)
19047544Skarels 		p->p_cpu = 0;
19147544Skarels 	else {
19247544Skarels 		p->p_slptime--;	/* the first time was done in schedcpu */
19347544Skarels 		while (newcpu && --p->p_slptime)
19447544Skarels 			newcpu = (int) decay_cpu(loadfac, newcpu);
19547544Skarels 		p->p_cpu = min(newcpu, UCHAR_MAX);
19647544Skarels 	}
19747544Skarels 	setpri(p);
19817541Skarels }
19917541Skarels 
20033Sbill #define SQSIZE 0100	/* Must be power of 2 */
20133Sbill #define HASH(x)	(( (int) x >> 5) & (SQSIZE-1))
20221099Smckusick struct slpque {
20321099Smckusick 	struct proc *sq_head;
20421099Smckusick 	struct proc **sq_tailp;
20521099Smckusick } slpque[SQSIZE];
20633Sbill 
20733Sbill /*
20845671Skarels  * During autoconfiguration or after a panic, a sleep will simply
20945671Skarels  * lower the priority briefly to allow interrupts, then return.
21045671Skarels  * The priority to be used (safepri) is machine-dependent, thus this
21145671Skarels  * value is initialized and maintained in the machine-dependent layers.
21245671Skarels  * This priority will typically be 0, or the lowest priority
21345671Skarels  * that is safe for use on the interrupt stack; it can be made
21445671Skarels  * higher to block network software interrupts after panics.
21545671Skarels  */
21645671Skarels int safepri;
21745671Skarels 
21845671Skarels /*
21940711Skarels  * General sleep call.
22040711Skarels  * Suspends current process until a wakeup is made on chan.
22140711Skarels  * The process will then be made runnable with priority pri.
22240711Skarels  * Sleeps at most timo/hz seconds (0 means no timeout).
22340711Skarels  * If pri includes PCATCH flag, signals are checked
22440711Skarels  * before and after sleeping, else signals are not checked.
22540711Skarels  * Returns 0 if awakened, EWOULDBLOCK if the timeout expires.
22640711Skarels  * If PCATCH is set and a signal needs to be delivered,
22740711Skarels  * ERESTART is returned if the current system call should be restarted
22840711Skarels  * if possible, and EINTR is returned if the system call should
22940711Skarels  * be interrupted by the signal (return EINTR).
23033Sbill  */
23140711Skarels tsleep(chan, pri, wmesg, timo)
23240710Smarc 	caddr_t chan;
23340710Smarc 	int pri;
23440710Smarc 	char *wmesg;
23540710Smarc 	int timo;
23640710Smarc {
237*49095Skarels 	register struct proc *p = curproc;
23840710Smarc 	register struct slpque *qp;
23940710Smarc 	register s;
24040711Skarels 	int sig, catch = pri & PCATCH;
24140710Smarc 	extern int cold;
24240710Smarc 	int endtsleep();
24340710Smarc 
24440710Smarc 	s = splhigh();
24540710Smarc 	if (cold || panicstr) {
24640710Smarc 		/*
24740710Smarc 		 * After a panic, or during autoconfiguration,
24840710Smarc 		 * just give interrupts a chance, then just return;
24940710Smarc 		 * don't run any other procs or panic below,
25040710Smarc 		 * in case this is the idle process and already asleep.
25140710Smarc 		 */
25245671Skarels 		splx(safepri);
25340710Smarc 		splx(s);
25440710Smarc 		return (0);
25540710Smarc 	}
25640710Smarc #ifdef DIAGNOSTIC
25747544Skarels 	if (chan == 0 || p->p_stat != SRUN || p->p_rlink)
25840711Skarels 		panic("tsleep");
25940710Smarc #endif
26047544Skarels 	p->p_wchan = chan;
26147544Skarels 	p->p_wmesg = wmesg;
26247544Skarels 	p->p_slptime = 0;
26347544Skarels 	p->p_pri = pri & PRIMASK;
26440710Smarc 	qp = &slpque[HASH(chan)];
26540710Smarc 	if (qp->sq_head == 0)
26647544Skarels 		qp->sq_head = p;
26740710Smarc 	else
26847544Skarels 		*qp->sq_tailp = p;
26947544Skarels 	*(qp->sq_tailp = &p->p_link) = 0;
27045671Skarels 	if (timo)
27147544Skarels 		timeout(endtsleep, (caddr_t)p, timo);
27240710Smarc 	/*
27347544Skarels 	 * We put ourselves on the sleep queue and start our timeout
27447544Skarels 	 * before calling CURSIG, as we could stop there, and a wakeup
27547544Skarels 	 * or a SIGCONT (or both) could occur while we were stopped.
27645671Skarels 	 * A SIGCONT would cause us to be marked as SSLEEP
27745671Skarels 	 * without resuming us, thus we must be ready for sleep
27845671Skarels 	 * when CURSIG is called.  If the wakeup happens while we're
27947544Skarels 	 * stopped, p->p_wchan will be 0 upon return from CURSIG.
28040710Smarc 	 */
28140711Skarels 	if (catch) {
28247544Skarels 		p->p_flag |= SSINTR;
28347544Skarels 		if (sig = CURSIG(p)) {
28447544Skarels 			if (p->p_wchan)
28547544Skarels 				unsleep(p);
28647544Skarels 			p->p_stat = SRUN;
28745671Skarels 			goto resume;
28840711Skarels 		}
28947544Skarels 		if (p->p_wchan == 0) {
29045671Skarels 			catch = 0;
29145671Skarels 			goto resume;
29240711Skarels 		}
29340710Smarc 	}
29447544Skarels 	p->p_stat = SSLEEP;
29540710Smarc 	(void) spl0();
29647544Skarels 	p->p_stats->p_ru.ru_nvcsw++;
29740710Smarc 	swtch();
29845671Skarels resume:
29947544Skarels 	curpri = p->p_usrpri;
30040710Smarc 	splx(s);
30147544Skarels 	p->p_flag &= ~SSINTR;
30247544Skarels 	if (p->p_flag & STIMO) {
30347544Skarels 		p->p_flag &= ~STIMO;
30445671Skarels 		if (catch == 0 || sig == 0)
30545671Skarels 			return (EWOULDBLOCK);
30645671Skarels 	} else if (timo)
30747544Skarels 		untimeout(endtsleep, (caddr_t)p);
30847544Skarels 	if (catch && (sig != 0 || (sig = CURSIG(p)))) {
30947544Skarels 		if (p->p_sigacts->ps_sigintr & sigmask(sig))
31040711Skarels 			return (EINTR);
31140711Skarels 		return (ERESTART);
31240711Skarels 	}
31340710Smarc 	return (0);
31440710Smarc }
31540710Smarc 
31640710Smarc /*
31740710Smarc  * Implement timeout for tsleep.
31840710Smarc  * If process hasn't been awakened (wchan non-zero),
31940710Smarc  * set timeout flag and undo the sleep.  If proc
32040710Smarc  * is stopped, just unsleep so it will remain stopped.
32140710Smarc  */
32240710Smarc endtsleep(p)
32340710Smarc 	register struct proc *p;
32440710Smarc {
32540710Smarc 	int s = splhigh();
32640710Smarc 
32740710Smarc 	if (p->p_wchan) {
32840710Smarc 		if (p->p_stat == SSLEEP)
32940710Smarc 			setrun(p);
33040710Smarc 		else
33140710Smarc 			unsleep(p);
33240710Smarc 		p->p_flag |= STIMO;
33340710Smarc 	}
33440710Smarc 	splx(s);
33540710Smarc }
33640710Smarc 
33740711Skarels /*
33840711Skarels  * Short-term, non-interruptable sleep.
33940711Skarels  */
34033Sbill sleep(chan, pri)
3418033Sroot 	caddr_t chan;
3428033Sroot 	int pri;
34333Sbill {
344*49095Skarels 	register struct proc *p = curproc;
34521099Smckusick 	register struct slpque *qp;
346207Sbill 	register s;
34730532Skarels 	extern int cold;
34833Sbill 
34940711Skarels #ifdef DIAGNOSTIC
35040711Skarels 	if (pri > PZERO) {
35140711Skarels 		printf("sleep called with pri %d > PZERO, wchan: %x\n",
35240711Skarels 			pri, chan);
35340711Skarels 		panic("old sleep");
35440711Skarels 	}
35540711Skarels #endif
35617541Skarels 	s = splhigh();
35730532Skarels 	if (cold || panicstr) {
35818363Skarels 		/*
35930532Skarels 		 * After a panic, or during autoconfiguration,
36030532Skarels 		 * just give interrupts a chance, then just return;
36130532Skarels 		 * don't run any other procs or panic below,
36230532Skarels 		 * in case this is the idle process and already asleep.
36318363Skarels 		 */
36445671Skarels 		splx(safepri);
36518363Skarels 		splx(s);
36618363Skarels 		return;
36718363Skarels 	}
36840710Smarc #ifdef DIAGNOSTIC
36947544Skarels 	if (chan==0 || p->p_stat != SRUN || p->p_rlink)
37033Sbill 		panic("sleep");
37140710Smarc #endif
37247544Skarels 	p->p_wchan = chan;
37347544Skarels 	p->p_wmesg = NULL;
37447544Skarels 	p->p_slptime = 0;
37547544Skarels 	p->p_pri = pri;
37621099Smckusick 	qp = &slpque[HASH(chan)];
37721099Smckusick 	if (qp->sq_head == 0)
37847544Skarels 		qp->sq_head = p;
37921099Smckusick 	else
38047544Skarels 		*qp->sq_tailp = p;
38147544Skarels 	*(qp->sq_tailp = &p->p_link) = 0;
38247544Skarels 	p->p_stat = SSLEEP;
38340711Skarels 	(void) spl0();
38447544Skarels 	p->p_stats->p_ru.ru_nvcsw++;
38540711Skarels 	swtch();
38647544Skarels 	curpri = p->p_usrpri;
38733Sbill 	splx(s);
38833Sbill }
38933Sbill 
39033Sbill /*
391181Sbill  * Remove a process from its wait queue
392181Sbill  */
393181Sbill unsleep(p)
3944826Swnj 	register struct proc *p;
395181Sbill {
39621099Smckusick 	register struct slpque *qp;
397181Sbill 	register struct proc **hp;
39821099Smckusick 	int s;
399181Sbill 
40017541Skarels 	s = splhigh();
401181Sbill 	if (p->p_wchan) {
40221099Smckusick 		hp = &(qp = &slpque[HASH(p->p_wchan)])->sq_head;
403181Sbill 		while (*hp != p)
404181Sbill 			hp = &(*hp)->p_link;
405181Sbill 		*hp = p->p_link;
40621099Smckusick 		if (qp->sq_tailp == &p->p_link)
40721099Smckusick 			qp->sq_tailp = hp;
408181Sbill 		p->p_wchan = 0;
409181Sbill 	}
410181Sbill 	splx(s);
411181Sbill }
412181Sbill 
413181Sbill /*
41447544Skarels  * Wakeup on "chan"; set all processes
41547544Skarels  * sleeping on chan to run state.
41633Sbill  */
41733Sbill wakeup(chan)
4184826Swnj 	register caddr_t chan;
41933Sbill {
42021099Smckusick 	register struct slpque *qp;
42121099Smckusick 	register struct proc *p, **q;
42233Sbill 	int s;
42333Sbill 
42417541Skarels 	s = splhigh();
42521099Smckusick 	qp = &slpque[HASH(chan)];
42633Sbill restart:
42721099Smckusick 	for (q = &qp->sq_head; p = *q; ) {
42840710Smarc #ifdef DIAGNOSTIC
429181Sbill 		if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP)
43033Sbill 			panic("wakeup");
43140710Smarc #endif
43247544Skarels 		if (p->p_wchan == chan) {
43333Sbill 			p->p_wchan = 0;
434187Sbill 			*q = p->p_link;
43521099Smckusick 			if (qp->sq_tailp == &p->p_link)
43621099Smckusick 				qp->sq_tailp = q;
437181Sbill 			if (p->p_stat == SSLEEP) {
438181Sbill 				/* OPTIMIZED INLINE EXPANSION OF setrun(p) */
43921763Skarels 				if (p->p_slptime > 1)
44021763Skarels 					updatepri(p);
44147544Skarels 				p->p_slptime = 0;
442181Sbill 				p->p_stat = SRUN;
4432702Swnj 				if (p->p_flag & SLOAD)
444181Sbill 					setrq(p);
44516795Skarels 				/*
44616795Skarels 				 * Since curpri is a usrpri,
44716795Skarels 				 * p->p_pri is always better than curpri.
44816795Skarels 				 */
44947544Skarels 				if ((p->p_flag&SLOAD) == 0)
45047544Skarels 					wakeup((caddr_t)&proc0);
45147544Skarels 				else
45247544Skarels 					need_resched();
453181Sbill 				/* END INLINE EXPANSION */
454187Sbill 				goto restart;
45533Sbill 			}
456187Sbill 		} else
457187Sbill 			q = &p->p_link;
45833Sbill 	}
45933Sbill 	splx(s);
46033Sbill }
46133Sbill 
46233Sbill /*
46333Sbill  * Initialize the (doubly-linked) run queues
46433Sbill  * to be empty.
46533Sbill  */
46633Sbill rqinit()
46733Sbill {
46833Sbill 	register int i;
46933Sbill 
47033Sbill 	for (i = 0; i < NQS; i++)
47133Sbill 		qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
47233Sbill }
47333Sbill 
47433Sbill /*
47547544Skarels  * Change process state to be runnable,
47647544Skarels  * placing it on the run queue if it is in memory,
47747544Skarels  * and awakening the swapper if it isn't in memory.
47833Sbill  */
47933Sbill setrun(p)
4804826Swnj 	register struct proc *p;
48133Sbill {
4824826Swnj 	register int s;
48333Sbill 
48417541Skarels 	s = splhigh();
48533Sbill 	switch (p->p_stat) {
48633Sbill 
48733Sbill 	case 0:
48833Sbill 	case SWAIT:
48933Sbill 	case SRUN:
49033Sbill 	case SZOMB:
49133Sbill 	default:
49233Sbill 		panic("setrun");
49333Sbill 
494207Sbill 	case SSTOP:
49533Sbill 	case SSLEEP:
496181Sbill 		unsleep(p);		/* e.g. when sending signals */
49733Sbill 		break;
49833Sbill 
49933Sbill 	case SIDL:
50033Sbill 		break;
50133Sbill 	}
50233Sbill 	p->p_stat = SRUN;
50333Sbill 	if (p->p_flag & SLOAD)
50433Sbill 		setrq(p);
50533Sbill 	splx(s);
50630232Skarels 	if (p->p_slptime > 1)
50730232Skarels 		updatepri(p);
50847544Skarels 	p->p_slptime = 0;
50947544Skarels 	if ((p->p_flag&SLOAD) == 0)
51047544Skarels 		wakeup((caddr_t)&proc0);
51147544Skarels 	else if (p->p_pri < curpri)
51247544Skarels 		need_resched();
51333Sbill }
51433Sbill 
51533Sbill /*
51647544Skarels  * Compute priority of process when running in user mode.
51747544Skarels  * Arrange to reschedule if the resulting priority
51847544Skarels  * is better than that of the current process.
51933Sbill  */
52047544Skarels setpri(p)
52147544Skarels 	register struct proc *p;
52233Sbill {
52347544Skarels 	register unsigned int newpri;
52433Sbill 
52547544Skarels 	newpri = PUSER + p->p_cpu / 4 + 2 * p->p_nice;
52647544Skarels 	newpri = min(newpri, MAXPRI);
52747544Skarels 	p->p_usrpri = newpri;
52847544Skarels 	if (newpri < curpri)
52947544Skarels 		need_resched();
53033Sbill }
531