diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index dba635d897db..b9b7269d3a4c 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -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) diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index e9cda3075a09..d3ae502b2433 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -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 @@ -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); diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index dba635d897db..b9b7269d3a4c 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -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) diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index e9cda3075a09..d3ae502b2433 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -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 @@ -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); diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index dba635d897db..b9b7269d3a4c 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -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) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index ffc458b9d98d..334db925a08c 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -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). */ diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 0e145a238dce..2ac184961db2 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -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); /* diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 24316160d8ca..b32fe038841b 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -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); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 1e905cab46cc..669567eaedfa 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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;