Use MI switch code for process selection. This gets run queues entirely
out of the asm code, and as a bonus implements rtprio and idprio for the Alpha. Previously if you ran an idprio process, you were assured of a deadlock.
This commit is contained in:
parent
8928d4404a
commit
8dd36a4d6a
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: machdep.c,v 1.47 1999/07/06 17:48:16 peter Exp $
|
||||
* $Id: machdep.c,v 1.48 1999/07/08 06:05:38 mckusick Exp $
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -1150,109 +1150,6 @@ DELAY(int n)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The following primitives manipulate the run queues. _whichqs tells which
|
||||
* of the 32 queues _qs have processes in them. Setrunqueue puts processes
|
||||
* into queues, Remrunqueue removes them from queues. The running process is
|
||||
* on no queue, other processes are on a queue related to p->p_priority,
|
||||
* divided by 4 actually to shrink the 0-127 range of priorities into the 32
|
||||
* available queues.
|
||||
*/
|
||||
|
||||
#define P_FORW(p) ((struct proc*) (p)->p_procq.tqe_next)
|
||||
#define P_BACK(p) ((struct proc*) (p)->p_procq.tqe_prev)
|
||||
|
||||
#define INSRQ(qs, whichqs, pri, p) \
|
||||
do { \
|
||||
whichqs |= (1 << pri); \
|
||||
P_FORW(p) = (struct proc *)&qs[pri]; \
|
||||
P_BACK(p) = qs[pri].ph_rlink; \
|
||||
P_FORW(P_BACK(p)) = p; \
|
||||
qs[pri].ph_rlink = p; \
|
||||
} while(0)
|
||||
|
||||
#define REMRQ(qs, whichqs, pri, p) \
|
||||
do { \
|
||||
if (!(whichqs & (1 << pri))) \
|
||||
panic(#whichqs); \
|
||||
P_FORW(P_BACK(p)) = P_FORW(p); \
|
||||
P_BACK(P_FORW(p)) = P_BACK(p); \
|
||||
P_BACK(p) = NULL; \
|
||||
if ((struct proc *)&qs[pri] == qs[pri].ph_link) \
|
||||
whichqs &= ~(1 << pri); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* setrunqueue(p)
|
||||
* proc *p;
|
||||
*
|
||||
* Call should be made at splclock(), and p->p_stat should be SRUN.
|
||||
*/
|
||||
void
|
||||
setrunqueue(p)
|
||||
struct proc *p;
|
||||
{
|
||||
int pri;
|
||||
|
||||
#if 0
|
||||
/* firewall: p->p_back must be NULL */
|
||||
if (p->p_procq.tqe_prev != NULL)
|
||||
panic("setrunqueue");
|
||||
#endif
|
||||
|
||||
if (p->p_rtprio.type == RTP_PRIO_NORMAL) {
|
||||
/* normal priority */
|
||||
pri = p->p_priority >> 2;
|
||||
INSRQ(qs, whichqs, pri, p);
|
||||
} else {
|
||||
/* realtime or idle */
|
||||
pri = p->p_rtprio.prio;
|
||||
if (p->p_rtprio.type == RTP_PRIO_REALTIME
|
||||
#ifdef P1003_1B
|
||||
|| p->p_rtprio.type == RTP_PRIO_FIFO
|
||||
#endif
|
||||
) {
|
||||
/* realtime priority */
|
||||
INSRQ(rtqs, whichrtqs, pri, p);
|
||||
} else {
|
||||
/* idle priority */
|
||||
INSRQ(idqs, whichidqs, pri, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remrq(p)
|
||||
*
|
||||
* Call should be made at splclock().
|
||||
*/
|
||||
void
|
||||
remrq(p)
|
||||
struct proc *p;
|
||||
{
|
||||
int pri;
|
||||
|
||||
if (p->p_rtprio.type == RTP_PRIO_NORMAL) {
|
||||
/* normal priority */
|
||||
pri = p->p_priority >> 2;
|
||||
REMRQ(qs, whichqs, pri, p);
|
||||
} else {
|
||||
/* realtime or idle */
|
||||
pri = p->p_rtprio.prio;
|
||||
if (p->p_rtprio.type == RTP_PRIO_REALTIME
|
||||
#ifdef P1003_1B
|
||||
|| p->p_rtprio.type == RTP_PRIO_FIFO
|
||||
#endif
|
||||
) {
|
||||
/* realtime priority */
|
||||
REMRQ(rtqs, whichrtqs, pri, p);
|
||||
} else {
|
||||
/* idle priority */
|
||||
REMRQ(idqs, whichidqs, pri, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an interrupt to process.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: swtch.s,v 1.8 1999/02/28 10:53:28 bde Exp $ */
|
||||
/* $Id: swtch.s,v 1.9 1999/04/16 13:57:38 gallatin Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -82,7 +82,6 @@ Lsavectx1: LDGP(pv)
|
|||
|
||||
/**************************************************************************/
|
||||
|
||||
IMPORT(whichqs, 4)
|
||||
IMPORT(want_resched, 4)
|
||||
IMPORT(Lev1map, 8)
|
||||
|
||||
|
@ -100,8 +99,8 @@ Lidle1: LDGP(pv)
|
|||
mov zero, a0 /* enable all interrupts */
|
||||
call_pal PAL_OSF1_swpipl
|
||||
Lidle2:
|
||||
ldl t0, whichqs /* look for non-empty queue */
|
||||
beq t0, Lidle2
|
||||
CALL(procrunnable)
|
||||
beq v0, Lidle2
|
||||
ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
|
||||
call_pal PAL_OSF1_swpipl
|
||||
jmp zero, sw1 /* jump back into the fray */
|
||||
|
@ -130,51 +129,17 @@ LEAF(cpu_switch, 1)
|
|||
mov a0, s0 /* save old curproc */
|
||||
mov a1, s1 /* save old U-area */
|
||||
|
||||
ldl t0, whichqs /* look for non-empty queue */
|
||||
beq t0, idle /* and if none, go idle */
|
||||
CALL(procrunnable) /* anything to run? */
|
||||
beq v0, idle /* and if none, go idle */
|
||||
|
||||
ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
|
||||
call_pal PAL_OSF1_swpipl
|
||||
sw1:
|
||||
br pv, Lcs1
|
||||
Lcs1: LDGP(pv)
|
||||
ldl t0, whichqs /* look for non-empty queue */
|
||||
beq t0, idle /* and if none, go idle */
|
||||
mov t0, t3 /* t3 = saved whichqs */
|
||||
mov zero, t2 /* t2 = lowest bit set */
|
||||
blbs t0, Lcs3 /* if low bit set, done! */
|
||||
|
||||
Lcs2: srl t0, 1, t0 /* try next bit */
|
||||
addq t2, 1, t2
|
||||
blbc t0, Lcs2 /* if clear, try again */
|
||||
|
||||
Lcs3:
|
||||
/*
|
||||
* Remove process from queue
|
||||
*/
|
||||
lda t1, qs /* get queues */
|
||||
sll t2, 4, t0 /* queue head is 16 bytes */
|
||||
addq t1, t0, t0 /* t0 = qp = &qs[firstbit] */
|
||||
|
||||
ldq t4, PH_LINK(t0) /* t4 = p = highest pri proc */
|
||||
ldq t5, P_FORW(t4) /* t5 = p->p_forw */
|
||||
bne t4, Lcs4 /* make sure p != NULL */
|
||||
PANIC("cpu_switch",Lcpu_switch_pmsg) /* nothing in queue! */
|
||||
|
||||
Lcs4:
|
||||
stq t5, PH_LINK(t0) /* qp->ph_link = p->p_forw */
|
||||
stq t0, P_BACK(t5) /* p->p_forw->p_back = qp */
|
||||
stq zero, P_BACK(t4) /* firewall: p->p_back = NULL */
|
||||
cmpeq t0, t5, t0 /* see if queue is empty */
|
||||
beq t0, Lcs5 /* nope, it's not! */
|
||||
|
||||
ldiq t0, 1 /* compute bit in whichqs */
|
||||
sll t0, t2, t0
|
||||
xor t3, t0, t3 /* clear bit in whichqs */
|
||||
stl t3, whichqs
|
||||
|
||||
Lcs5:
|
||||
mov t4, s2 /* save new proc */
|
||||
CALL(chooseproc)
|
||||
beq v0, idle
|
||||
mov v0, s2
|
||||
ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
|
||||
|
||||
/*
|
||||
|
@ -187,7 +152,7 @@ Lcs5:
|
|||
* saved it. Also note that switch_exit() ensures that
|
||||
* s0 is clear before jumping here to find a new process.
|
||||
*/
|
||||
cmpeq s0, t4, t0 /* oldproc == newproc? */
|
||||
cmpeq s0, s2, t0 /* oldproc == newproc? */
|
||||
bne t0, Lcs7 /* Yes! Skip! */
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue