Converted timer/run queues to 4.4BSD queue style. Removed old and unused

sleep(). Implemented wakeup_one() which may be used in the future to combat
the "thundering herd" problem for some special cases.

Reviewed by:	dyson
This commit is contained in:
David Greenman 1996-07-31 09:26:54 +00:00
parent 764f59345d
commit b1508c72f4
9 changed files with 102 additions and 177 deletions

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: swtch.s,v 1.36 1996/06/25 19:25:25 bde Exp $
* $Id: swtch.s,v 1.37 1996/06/25 20:01:59 bde Exp $
*/
#include "apm.h"
@ -82,11 +82,13 @@ _want_resched: .long 0 /* we need to re-run the scheduler */
*/
ENTRY(setrunqueue)
movl 4(%esp),%eax
cmpl $0,P_BACK(%eax) /* should not be on q already */
#ifdef DIAGNOSTIC
cmpb $SRUN,P_STAT(%eax)
je set1
pushl $set2
call _panic
set1:
#endif
cmpw $RTP_PRIO_NORMAL,P_RTPRIO_TYPE(%eax) /* normal priority process? */
je set_nort
@ -168,7 +170,6 @@ rem1rt:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichrtqs
rem2rt:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_id:
btrl %edx,_whichidqs /* clear full bit, panic if clear already */
@ -192,7 +193,6 @@ rem1id:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichidqs
rem2id:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_nort:
@ -219,7 +219,6 @@ rem1:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichqs
rem2:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem3: .asciz "remrq"
@ -334,11 +333,6 @@ sw1a:
leal _rtqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -366,11 +360,6 @@ nortqr:
leal _qs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -396,11 +385,6 @@ idqr: /* was sw1a */
leal _idqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.35 1996/05/02 14:19:40 phk Exp $
* $Id: genassym.c,v 1.36 1996/05/02 22:24:53 phk Exp $
*/
#include <stdio.h>
@ -85,8 +85,8 @@ main()
struct sigframe *sigf = (struct sigframe *)0;
struct bootinfo *bootinfo = (struct bootinfo *)0;
printf("#define\tP_FORW %p\n", &p->p_forw);
printf("#define\tP_BACK %p\n", &p->p_back);
printf("#define\tP_FORW %p\n", &p->p_procq.tqe_next);
printf("#define\tP_BACK %p\n", &p->p_procq.tqe_prev);
printf("#define\tP_VMSPACE %p\n", &p->p_vmspace);
printf("#define\tVM_PMAP %p\n", &vms->vm_pmap);
printf("#define\tP_ADDR %p\n", &p->p_addr);

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: swtch.s,v 1.36 1996/06/25 19:25:25 bde Exp $
* $Id: swtch.s,v 1.37 1996/06/25 20:01:59 bde Exp $
*/
#include "apm.h"
@ -82,11 +82,13 @@ _want_resched: .long 0 /* we need to re-run the scheduler */
*/
ENTRY(setrunqueue)
movl 4(%esp),%eax
cmpl $0,P_BACK(%eax) /* should not be on q already */
#ifdef DIAGNOSTIC
cmpb $SRUN,P_STAT(%eax)
je set1
pushl $set2
call _panic
set1:
#endif
cmpw $RTP_PRIO_NORMAL,P_RTPRIO_TYPE(%eax) /* normal priority process? */
je set_nort
@ -168,7 +170,6 @@ rem1rt:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichrtqs
rem2rt:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_id:
btrl %edx,_whichidqs /* clear full bit, panic if clear already */
@ -192,7 +193,6 @@ rem1id:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichidqs
rem2id:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_nort:
@ -219,7 +219,6 @@ rem1:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichqs
rem2:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem3: .asciz "remrq"
@ -334,11 +333,6 @@ sw1a:
leal _rtqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -366,11 +360,6 @@ nortqr:
leal _qs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -396,11 +385,6 @@ idqr: /* was sw1a */
leal _idqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.35 1996/05/02 14:19:40 phk Exp $
* $Id: genassym.c,v 1.36 1996/05/02 22:24:53 phk Exp $
*/
#include <stdio.h>
@ -85,8 +85,8 @@ main()
struct sigframe *sigf = (struct sigframe *)0;
struct bootinfo *bootinfo = (struct bootinfo *)0;
printf("#define\tP_FORW %p\n", &p->p_forw);
printf("#define\tP_BACK %p\n", &p->p_back);
printf("#define\tP_FORW %p\n", &p->p_procq.tqe_next);
printf("#define\tP_BACK %p\n", &p->p_procq.tqe_prev);
printf("#define\tP_VMSPACE %p\n", &p->p_vmspace);
printf("#define\tVM_PMAP %p\n", &vms->vm_pmap);
printf("#define\tP_ADDR %p\n", &p->p_addr);

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: swtch.s,v 1.36 1996/06/25 19:25:25 bde Exp $
* $Id: swtch.s,v 1.37 1996/06/25 20:01:59 bde Exp $
*/
#include "apm.h"
@ -82,11 +82,13 @@ _want_resched: .long 0 /* we need to re-run the scheduler */
*/
ENTRY(setrunqueue)
movl 4(%esp),%eax
cmpl $0,P_BACK(%eax) /* should not be on q already */
#ifdef DIAGNOSTIC
cmpb $SRUN,P_STAT(%eax)
je set1
pushl $set2
call _panic
set1:
#endif
cmpw $RTP_PRIO_NORMAL,P_RTPRIO_TYPE(%eax) /* normal priority process? */
je set_nort
@ -168,7 +170,6 @@ rem1rt:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichrtqs
rem2rt:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_id:
btrl %edx,_whichidqs /* clear full bit, panic if clear already */
@ -192,7 +193,6 @@ rem1id:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichidqs
rem2id:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem_nort:
@ -219,7 +219,6 @@ rem1:
shrl $3,%edx /* yes, set bit as still full */
btsl %edx,_whichqs
rem2:
movl $0,P_BACK(%eax) /* zap reverse link to indicate off list */
ret
rem3: .asciz "remrq"
@ -334,11 +333,6 @@ sw1a:
leal _rtqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -366,11 +360,6 @@ nortqr:
leal _qs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)
@ -396,11 +385,6 @@ idqr: /* was sw1a */
leal _idqs(,%ebx,8),%eax /* select q */
movl %eax,%esi
#ifdef DIAGNOSTIC
cmpl P_FORW(%eax),%eax /* linked to self? (e.g. not on list) */
je badsw /* not possible */
#endif
movl P_FORW(%eax),%ecx /* unlink from front of process q */
movl P_FORW(%ecx),%edx
movl %edx,P_FORW(%eax)

View File

@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
* $Id: init_main.c,v 1.42 1996/06/11 23:50:48 dyson Exp $
* $Id: init_main.c,v 1.43 1996/06/14 11:01:25 asami Exp $
*/
#include "opt_rlimit.h"
@ -337,6 +337,11 @@ proc0_init(dummy)
*/
procinit();
/*
* Initialize sleep queue hash table
*/
sleepinit();
/*
* Create process 0 (the swapper).
*/

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $Id: kern_fork.c,v 1.21 1996/05/02 11:38:05 peter Exp $
* $Id: kern_fork.c,v 1.22 1996/06/12 05:07:30 gpalmer Exp $
*/
#include "opt_ktrace.h"
@ -205,7 +205,6 @@ fork1(p1, flags, retval)
p2->p_stat = SIDL; /* protect against others */
p2->p_pid = nextpid;
LIST_INSERT_HEAD(&allproc, p2, p_list);
p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
/*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
* $Id: kern_synch.c,v 1.19 1996/03/11 05:48:57 hsu Exp $
* $Id: kern_synch.c,v 1.20 1996/04/07 13:35:58 bde Exp $
*/
#include "opt_ktrace.h"
@ -260,11 +260,8 @@ updatepri(p)
* of 2. Shift right by 8, i.e. drop the bottom 256 worth.
*/
#define TABLESIZE 128
TAILQ_HEAD(slpquehead, proc) slpque[TABLESIZE];
#define LOOKUP(x) (((long)(x) >> 8) & (TABLESIZE - 1))
struct slpque {
struct proc *sq_head;
struct proc **sq_tailp;
} slpque[TABLESIZE];
/*
* During autoconfiguration or after a panic, a sleep will simply
@ -277,6 +274,15 @@ struct slpque {
*/
int safepri;
void
sleepinit()
{
int i;
for (i = 0; i < TABLESIZE; i++)
TAILQ_INIT(&slpque[i]);
}
/*
* General sleep call. Suspends the current process until a wakeup is
* performed on the specified identifier. The process will then be made
@ -294,10 +300,8 @@ tsleep(ident, priority, wmesg, timo)
int priority, timo;
char *wmesg;
{
register struct proc *p = curproc;
register struct slpque *qp;
register s;
int sig, catch = priority & PCATCH;
struct proc *p = curproc;
int s, sig, catch = priority & PCATCH;
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
@ -316,19 +320,14 @@ tsleep(ident, priority, wmesg, timo)
return (0);
}
#ifdef DIAGNOSTIC
if (ident == NULL || p->p_stat != SRUN || p->p_back)
if (ident == NULL || p->p_stat != SRUN)
panic("tsleep");
#endif
p->p_wchan = ident;
p->p_wmesg = wmesg;
p->p_slptime = 0;
p->p_priority = priority & PRIMASK;
qp = &slpque[LOOKUP(ident)];
if (qp->sq_head == 0)
qp->sq_head = p;
else
*qp->sq_tailp = p;
*(qp->sq_tailp = &p->p_forw) = 0;
TAILQ_INSERT_TAIL(&slpque[LOOKUP(ident)], p, p_procq);
if (timo)
timeout(endtsleep, (void *)p, timo);
/*
@ -413,68 +412,6 @@ endtsleep(arg)
splx(s);
}
#if 0
/*
* Short-term, non-interruptable sleep.
*/
void
sleep(ident, priority)
void *ident;
int priority;
{
register struct proc *p = curproc;
register struct slpque *qp;
register s;
#ifdef DIAGNOSTIC
if (priority > PZERO) {
printf("sleep called with priority %d > PZERO, wchan: %p\n",
priority, ident);
panic("old sleep");
}
#endif
s = splhigh();
if (cold || panicstr) {
/*
* After a panic, or during autoconfiguration,
* just give interrupts a chance, then just return;
* don't run any other procs or panic below,
* in case this is the idle process and already asleep.
*/
splx(safepri);
splx(s);
return;
}
#ifdef DIAGNOSTIC
if (ident == NULL || p->p_stat != SRUN || p->p_back)
panic("sleep");
#endif
p->p_wchan = ident;
p->p_wmesg = NULL;
p->p_slptime = 0;
p->p_priority = priority;
qp = &slpque[LOOKUP(ident)];
if (qp->sq_head == 0)
qp->sq_head = p;
else
*qp->sq_tailp = p;
*(qp->sq_tailp = &p->p_forw) = 0;
p->p_stat = SSLEEP;
p->p_stats->p_ru.ru_nvcsw++;
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
ktrcsw(p->p_tracep, 1, 0);
#endif
mi_switch();
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
ktrcsw(p->p_tracep, 0, 0);
#endif
curpriority = p->p_usrpri;
splx(s);
}
#endif
/*
* Remove a process from its wait queue
*/
@ -482,18 +419,11 @@ void
unsleep(p)
register struct proc *p;
{
register struct slpque *qp;
register struct proc **hp;
int s;
s = splhigh();
if (p->p_wchan) {
hp = &(qp = &slpque[LOOKUP(p->p_wchan)])->sq_head;
while (*hp != p)
hp = &(*hp)->p_forw;
*hp = p->p_forw;
if (qp->sq_tailp == &p->p_forw)
qp->sq_tailp = hp;
TAILQ_REMOVE(&slpque[LOOKUP(p->p_wchan)], p, p_procq);
p->p_wchan = 0;
}
splx(s);
@ -506,46 +436,84 @@ void
wakeup(ident)
register void *ident;
{
register struct slpque *qp;
register struct proc *p, **q;
register struct slpquehead *qp;
register struct proc *p;
int s;
s = splhigh();
qp = &slpque[LOOKUP(ident)];
restart:
for (q = &qp->sq_head; *q; ) {
p = *q;
for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) {
#ifdef DIAGNOSTIC
if (p->p_back || (p->p_stat != SSLEEP && p->p_stat != SSTOP))
if (p->p_stat != SSLEEP && p->p_stat != SSTOP)
panic("wakeup");
#endif
if (p->p_wchan == ident) {
TAILQ_REMOVE(qp, p, p_procq);
p->p_wchan = 0;
*q = p->p_forw;
if (qp->sq_tailp == &p->p_forw)
qp->sq_tailp = q;
if (p->p_stat == SSLEEP) {
/* OPTIMIZED EXPANSION OF setrunnable(p); */
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
p->p_stat = SRUN;
if (p->p_flag & P_INMEM)
if (p->p_flag & P_INMEM) {
setrunqueue(p);
/*
* Since curpriority is a user priority,
* p->p_priority is always better than
* curpriority.
*/
if ((p->p_flag & P_INMEM) == 0)
wakeup((caddr_t)&proc0);
else
need_resched();
} else {
wakeup((caddr_t)&proc0);
}
/* END INLINE EXPANSION */
goto restart;
}
} else
q = &p->p_forw;
}
}
splx(s);
}
/*
* Make one process sleeping on the specified identifier runnable.
*/
void
wakeup_one(ident)
register void *ident;
{
register struct slpquehead *qp;
register struct proc *p;
int s;
s = splhigh();
qp = &slpque[LOOKUP(ident)];
for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) {
#ifdef DIAGNOSTIC
if (p->p_stat != SSLEEP && p->p_stat != SSTOP)
panic("wakeup_one");
#endif
if (p->p_wchan == ident) {
TAILQ_REMOVE(qp, p, p_procq);
p->p_wchan = 0;
if (p->p_stat == SSLEEP) {
/* OPTIMIZED EXPANSION OF setrunnable(p); */
if (p->p_slptime > 1)
updatepri(p);
p->p_slptime = 0;
p->p_stat = SRUN;
/*
* XXX Perhaps we should only terminate the
* loop if the process being awoken is memory
* resident (i.e. actually runnable)?
*/
if (p->p_flag & P_INMEM) {
setrunqueue(p);
need_resched();
} else {
wakeup((caddr_t)&proc0);
}
/* END INLINE EXPANSION */
break;
}
}
}
splx(s);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.15 (Berkeley) 5/19/95
* $Id: proc.h,v 1.24 1996/05/01 02:52:05 bde Exp $
* $Id: proc.h,v 1.25 1996/06/09 15:00:11 alex Exp $
*/
#ifndef _SYS_PROC_H_
@ -83,8 +83,7 @@ struct pgrp {
* is running.
*/
struct proc {
struct proc *p_forw; /* Doubly-linked run/sleep queue. */
struct proc *p_back;
TAILQ_ENTRY(proc) p_procq; /* run/sleep queue. */
LIST_ENTRY(proc) p_list; /* List of all processes. */
/* substructures: */
@ -295,11 +294,13 @@ void roundrobin __P((void *));
void schedcpu __P((void *));
void setrunnable __P((struct proc *));
void setrunqueue __P((struct proc *));
void sleepinit __P((void));
void remrq __P((struct proc *));
void cpu_switch __P((struct proc *));
int tsleep __P((void *chan, int pri, char *wmesg, int timo));
void unsleep __P((struct proc *));
void wakeup __P((void *chan));
void wakeup_one __P((void *chan));
__dead void cpu_exit __P((struct proc *)) __dead2;
__dead void exit1 __P((struct proc *, int)) __dead2;