Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/nathanw_sa]: src/sys/arch/arm/arm32 Check to see if the incoming LWP has...
details: https://anonhg.NetBSD.org/src/rev/5945f08e8439
branches: nathanw_sa
changeset: 506168:5945f08e8439
user: thorpej <thorpej%NetBSD.org@localhost>
date: Tue Aug 20 15:21:29 2002 +0000
description:
Check to see if the incoming LWP has the same L1 table as the
outgoing LWP. If so, then we can skip the cache purge and TTB
reload. This results in a ~40% reduction in cache purges called
from cpu_switch() in my test using two threaded applications which
communicate with each other.
diffstat:
sys/arch/arm/arm32/cpuswitch.S | 83 ++++++++++++++++++++++++++++++++---------
1 files changed, 65 insertions(+), 18 deletions(-)
diffs (165 lines):
diff -r 18d774b6d8c6 -r 5945f08e8439 sys/arch/arm/arm32/cpuswitch.S
--- a/sys/arch/arm/arm32/cpuswitch.S Mon Aug 19 22:25:45 2002 +0000
+++ b/sys/arch/arm/arm32/cpuswitch.S Tue Aug 20 15:21:29 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.3.2.20 2002/08/19 21:39:00 thorpej Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.3.2.21 2002/08/20 15:21:29 thorpej Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@@ -514,6 +514,19 @@
stmia r7, {r8-r13}
/*
+ * NOTE: We can now use r8-r13 until it is time to restore
+ * them for the new process.
+ */
+
+ /* Remember the old PCB. */
+ mov r8, r1
+
+ /* r1 now free! */
+
+ /* Get the user structure for the new process in r9 */
+ ldr r9, [r6, #(L_ADDR)]
+
+ /*
* This can be optimised... We know we want to go from SVC32
* mode to UND32 mode
*/
@@ -522,28 +535,47 @@
orr r2, r2, #(PSR_UND32_MODE | I32_bit)
msr cpsr_c, r2
- str sp, [r1, #(PCB_UND_SP)]
+ str sp, [r8, #(PCB_UND_SP)]
msr cpsr_c, r3 /* Restore the old mode */
/* rem: r0 = old lwp */
- /* rem: r1 = old pcb */
/* rem: r4 = return value */
/* rem: r6 = new process */
+ /* rem: r8 = old PCB */
+ /* rem: r9 = new PCB */
/* rem: interrupts are enabled */
/* What else needs to be saved Only FPA stuff when that is supported */
- /* r1 now free! */
-
/* Third phase : restore saved context */
/* rem: r0 = old lwp */
/* rem: r4 = return value */
/* rem: r6 = new lwp */
+ /* rem: r8 = old PCB */
+ /* rem: r9 = new PCB */
/* rem: interrupts are enabled */
/*
+ * Get the new L1 table pointer into r11. If we're switching to
+ * an LWP with the same address space as the outgoing one, we can
+ * skip the cache purge and the TTB load.
+ *
+ * To avoid data dep stalls that would happen anyway, we try
+ * and get some useful work done in the mean time.
+ */
+ ldr r10, [r8, #(PCB_PAGEDIR)] /* r10 = old L1 */
+ ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
+
+ ldr r3, .Lblock_userspace_access
+ mov r1, #0x00000001
+ mov r2, #0x00000000
+
+ teq r10, r11 /* r10 == r11? */
+ beq .Lcs_context_switched /* yes! */
+
+ /*
* Don't allow user space access between the purge and the switch.
*/
ldr r3, .Lblock_userspace_access
@@ -563,6 +595,13 @@
/* At this point we need to kill IRQ's again. */
IRQdisable
+ /* rem: r2 = 0 */
+ /* rem: r3 = &block_userspace_access */
+ /* rem: r4 = return value */
+ /* rem: r6 = new lwp */
+ /* rem: r9 = new PCB */
+ /* rem: r11 == new L1 */
+
/*
* Interrupts are disabled so we can allow user space accesses again
* as none will occur until interrupts are re-enabled after the
@@ -570,18 +609,17 @@
*/
str r2, [r3]
- /* Get the user structure for the new process in r1 */
- ldr r1, [r6, #(L_ADDR)]
-
- /* Get the pagedir physical address for the process. */
- ldr r0, [r1, #(PCB_PAGEDIR)]
-
/* Switch the memory to the new process */
ldr r3, .Lcpufuncs
+ mov r0, r11
add lr, pc, #.Lcs_context_switched - . - 8
ldr pc, [r3, #CF_CONTEXT_SWITCH]
-
+
.Lcs_context_switched:
+ /* rem: r4 = return value */
+ /* rem: r6 = new lwp */
+ /* rem: r9 = new PCB */
+
/*
* This can be optimised... We know we want to go from SVC32
* mode to UND32 mode
@@ -591,20 +629,27 @@
orr r2, r2, #(PSR_UND32_MODE)
msr cpsr_c, r2
- ldr sp, [r1, #(PCB_UND_SP)]
+ ldr sp, [r9, #(PCB_UND_SP)]
msr cpsr_c, r3 /* Restore the old mode */
- /* Restore all the save registers */
- add r7, r1, #PCB_R8
- ldmia r7, {r8-r13}
-
#ifdef ARMFPE
- add r0, r1, #(USER_SIZE) & 0x00ff
+ add r0, r9, #(USER_SIZE) & 0x00ff
add r0, r0, #(USER_SIZE) & 0xff00
bl _C_LABEL(arm_fpe_core_changecontext)
#endif
+ /* Restore all the save registers */
+ add r7, r9, #PCB_R8
+ ldmia r7, {r8-r13}
+
+ /*
+ * NOTE: We can now no longer use r8-r13.
+ */
+
+ /* rem: r4 = return value */
+ /* rem: r6 = new lwp */
+
/* We can enable interrupts again */
IRQenable
@@ -630,8 +675,10 @@
* expects. Userpsace access already blocked by switch_exit()/
* switch_lwp_exit().
*/
+ ldr r9, [r6, #(L_ADDR)] /* r9 = new PCB */
ldr r3, .Lblock_userspace_access
mov r2, #0x00000000
+ ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
b .Lcs_cache_purge_skipped
/*
Home |
Main Index |
Thread Index |
Old Index