summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/irq_asm.S
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-07-01 10:48:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-07-04 13:17:19 +0200
commitfbda4a8834c5c88c138466fb94c4004be7d72d66 (patch)
treeda13bb222edf9c59b3923357e23fc6545c255f8a /c/src/lib/libbsp/sparc/shared/irq_asm.S
parentarm: Use local label in _CPU_Context_restore() (diff)
downloadrtems-fbda4a8834c5c88c138466fb94c4004be7d72d66.tar.bz2
score: PR2183: Fix context switch on SMP
Fix context switch on SMP for ARM, PowerPC and SPARC. Atomically test and set the is executing indicator of the heir context to ensure that at most one processor uses the heir context. Break the busy wait loop also due to heir updates.
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/irq_asm.S')
-rw-r--r--c/src/lib/libbsp/sparc/shared/irq_asm.S57
1 files changed, 49 insertions, 8 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S
index bf2dca9787..2ab0defa72 100644
--- a/c/src/lib/libbsp/sparc/shared/irq_asm.S
+++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S
@@ -7,6 +7,8 @@
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2014 embedded brains GmbH
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
@@ -165,17 +167,18 @@ done_flushing:
#if defined(RTEMS_SMP)
! The executing context no longer executes on this processor
- stb %g0, [%o0 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
+ st %g0, [%o0 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
+
+ ! Try to update the is executing indicator of the heir context
+ mov 1, %g1
+
+try_update_is_executing:
- ! Wait for heir context to stop execution
-1:
- ldub [%o1 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET], %g1
+ swap [%o1 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET], %g1
cmp %g1, 0
- bne 1b
- mov 1, %g1
+ bne check_is_executing
- ! The heir context executes now on this processor
- stb %g1, [%o1 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
+ ! The next load is in a delay slot, which is all right
#endif
ld [%o1 + G5_OFFSET], %g5 ! restore the global registers
@@ -203,6 +206,44 @@ done_flushing:
jmp %o7 + 8 ! return
nop ! delay slot
+#if defined(RTEMS_SMP)
+check_is_executing:
+
+ ! Check the is executing indicator of the heir context
+ ld [%o1 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET], %g1
+ cmp %g1, 0
+ beq try_update_is_executing
+ mov 1, %g1
+
+ ! Check if a thread dispatch is necessary
+ ldub [%g6 + PER_CPU_DISPATCH_NEEDED], %g1
+ cmp %g1, 0
+ beq check_is_executing
+ nop
+
+ ! We have a new heir
+
+ ! Clear the thread dispatch necessary flag
+ stub %g0, [%g6 + PER_CPU_DISPATCH_NEEDED]
+
+ ! Here we assume a strong memory order, otherwise a memory barrier must
+ ! be inserted here
+
+ ! Read the executing and heir
+ ld [%g6 + PER_CPU_OFFSET_EXECUTING], %g1
+ ld [%g6 + PER_CPU_OFFSET_HEIR], %g2
+
+ ! Calculate the heir context pointer
+ sub %o1, %g1, %g1
+ add %g1, %g2, %o1
+
+ ! Update the executing
+ st %g2, [%g6 + PER_CPU_OFFSET_EXECUTING]
+
+ ba try_update_is_executing
+ mov 1, %g1
+#endif
+
/*
* void _CPU_Context_restore(
* Context_Control *new_context