diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-10-10 15:53:54 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-10-10 15:53:54 +0000 |
commit | e51062c8cca21a333603b567563e3b84f74ddac0 (patch) | |
tree | dccf12b7d5ef806260203fe60b2bcaf94260c651 /sys/arch/mvme68k | |
parent | 34c540de32da6090afdcdd6fee481f9a2df345fd (diff) |
Make context switching much more MI:
- Move the functionality of choosing a process from cpu_switch into
a much simpler function: cpu_switchto. Instead of having the locore
code walk the run queues, let the MI code choose the process we
want to run and only implement the context switching itself in MD
code.
- Let MD context switching run without worrying about spls or locks.
- Instead of having the idle loop implemented with special contexts
in MD code, implement one idle proc for each cpu. make the idle
loop MI with MD hooks.
- Change the proc lists from the old style vax queues to TAILQs.
- Change the sleep queue from vax queues to TAILQs. This makes
wakeup() go from O(n^2) to O(n)
there will be some MD fallout, but it will be fixed shortly.
There's also a few cleanups to be done after this.
deraadt@, kettenis@ ok
Diffstat (limited to 'sys/arch/mvme68k')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/locore.s | 100 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/vm_machdep.c | 16 |
2 files changed, 19 insertions, 97 deletions
diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index 38015370541..c92d4fb2978 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.54 2007/05/15 13:46:22 martin Exp $ */ +/* $OpenBSD: locore.s,v 1.55 2007/10/10 15:53:52 art Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -1165,51 +1165,18 @@ Ldorte: */ #include <m68k/m68k/support.s> -/* - * Use common m68k process manipulation routines. - */ -#include <m68k/m68k/proc_subr.s> - .data GLOBAL(curpcb) .long 0 ASBSS(nullpcb,SIZEOF_PCB) -/* - * At exit of a process, do a switch for the last time. - * Switch to a safe stack and PCB, and deallocate the process's resources. - */ -ENTRY(switch_exit) - movl sp@(4),a0 - | save state into garbage pcb - movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb) - lea _ASM_LABEL(tmpstk),sp | goto a tmp stack - - /* Schedule the vmspace and stack to be freed. */ - movl a0,sp@- | exit2(p) - jbsr _C_LABEL(exit2) - lea sp@(4),sp | pop args - - jra _C_LABEL(cpu_switch) - -/* - * When no processes are on the runq, Swtch branches to Idle - * to wait for something to come ready. - */ -ASENTRY_NOPROFILE(Idle) +ENTRY_NOPROFILE(cpu_idle_cycle) stop #PSL_LOWIPL - movw #PSL_HIGHIPL,sr - movl _C_LABEL(whichqs),d0 - jeq _ASM_LABEL(Idle) - jra Lsw1 - -Lbadsw: - PANIC("switch") - /*NOTREACHED*/ + rts /* - * cpu_switch() + * cpu_switchto(struct proc *oldproc, struct proc *newproc) * * NOTE: On the mc68851 we attempt to avoid flushing the * entire ATC. The effort involved in selective flushing may not be @@ -1219,55 +1186,15 @@ Lbadsw: * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag * bit). For now, we just always flush the full ATC. */ -ENTRY(cpu_switch) - movl _C_LABEL(curpcb),a0 | current pcb - movw sr,a0@(PCB_PS) | save sr before changing ipl -#ifdef notyet - movl CURPROC,sp@- | remember last proc running -#endif - clrl CURPROC +ENTRY(cpu_switchto) + movl sp@(4), d0 | oldproc + beq Lswnofpsave | is NULL, don't save anything /* - * Find the highest-priority queue that isn't empty, - * then take the first proc from that queue. - */ - movw #PSL_HIGHIPL,sr | lock out interrupts - movl _C_LABEL(whichqs),d0 - jeq _ASM_LABEL(Idle) -Lsw1: - movl d0,d1 - negl d0 - andl d1,d0 - bfffo d0{#0:#32},d1 - eorib #31,d1 - - movl d1,d0 - lslb #3,d1 | convert queue number to index - addl #_C_LABEL(qs),d1 | locate queue (q) - movl d1,a1 - movl a1@(P_FORW),a0 | p = q->p_forw - cmpal d1,a0 | anyone on queue? - jeq Lbadsw | no, panic - movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw - movl a0@(P_FORW),a1 | n = p->p_forw - movl d1,a1@(P_BACK) | n->p_back = q - cmpal d1,a1 | anyone left on queue? - jne Lsw2 | yes, skip - movl _C_LABEL(whichqs),d1 - bclr d0,d1 | no, clear bit - movl d1,_C_LABEL(whichqs) -Lsw2: - movl a0,CURPROC - clrl _C_LABEL(want_resched) -#ifdef notyet - movl sp@+,a1 - cmpl a0,a1 | switching to same proc? - jeq Lswdone | yes, skip save and restore -#endif - /* * Save state of previous process in its pcb. */ movl _C_LABEL(curpcb),a1 + movw sr, a1@(PCB_PS) | save sr before switching context moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers movl usp,a2 | grab USP (a2 has been saved) movl a2,a1@(PCB_USP) | and save it @@ -1295,15 +1222,12 @@ Lsavfp60: fmovem fpsr,a2@(FPF_FPSR) fmovem fpi,a2@(FPF_FPI) #endif /* M68060 */ + Lswnofpsave: -#ifdef DIAGNOSTIC - tstl a0@(P_WCHAN) - jne Lbadsw - cmpb #SRUN,a0@(P_STAT) - jne Lbadsw -#endif + movl sp@(8), a0 | newproc + + movl a0, CURPROC movb #SONPROC,a0@(P_STAT) - clrl a0@(P_BACK) | clear back link movl a0@(P_ADDR),a1 | get p_addr movl a1,_C_LABEL(curpcb) diff --git a/sys/arch/mvme68k/mvme68k/vm_machdep.c b/sys/arch/mvme68k/mvme68k/vm_machdep.c index e8ac2262a05..df44535cfda 100644 --- a/sys/arch/mvme68k/mvme68k/vm_machdep.c +++ b/sys/arch/mvme68k/mvme68k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.45 2007/06/20 17:29:36 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.46 2007/10/10 15:53:52 art Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -117,20 +117,18 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) /* * cpu_exit is called as the last action during exit. - * We release the address space and machine-dependent resources, - * including the memory for the user structure and kernel stack. - * Once finished, we call switch_exit, which switches to a temporary - * pcb and stack and never returns. We block memory allocation - * until switch_exit has made things safe again. + * + * Block context switches and then call switch_exit() which will + * switch to another process thus we never return. */ void cpu_exit(p) struct proc *p; { + (void)splhigh(); - splhigh(); - switch_exit(p); - /* NOTREACHED */ + pmap_deactivate(p); + sched_exit(p); } /* |