summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/new-exceptions
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-25 14:34:24 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-28 13:56:57 +0200
commit258ad71e9626c16f30b40e06c321326636c976ff (patch)
treeda6e210947d590159796434bf04cf364247ac20a /c/src/lib/libcpu/powerpc/new-exceptions
parentSMP: Simplify thread lock operations (diff)
downloadrtems-258ad71e9626c16f30b40e06c321326636c976ff.tar.bz2
SMP: Fix and optimize thread dispatching
According to the C11 and C++11 memory models only a read-modify-write operation guarantees that we read the last value written in modification order. Avoid the sequential consistent thread fence and instead use the inter-processor interrupt to set the thread dispatch necessary indicator.
Diffstat (limited to 'c/src/lib/libcpu/powerpc/new-exceptions')
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S25
1 files changed, 11 insertions, 14 deletions
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
index 5d8c70d290..8bfef20043 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
@@ -413,12 +413,12 @@ check_is_executing:
addi r6, r5, PPC_CONTEXT_OFFSET_IS_EXECUTING
lwarx r7, r0, r6
cmpwi r7, 0
- bne check_thread_dispatch_necessary
+ bne get_potential_new_heir
/* Try to update the is executing indicator of the heir context */
li r7, 1
stwcx. r7, r0, r6
- bne check_thread_dispatch_necessary
+ bne get_potential_new_heir
isync
#endif
@@ -536,26 +536,23 @@ PROC (_CPU_Context_restore):
b restore_context
#ifdef RTEMS_SMP
-check_thread_dispatch_necessary:
+get_potential_new_heir:
GET_SELF_CPU_CONTROL r6
- /* Check if a thread dispatch is necessary */
- lbz r7, PER_CPU_DISPATCH_NEEDED(r6)
- cmpwi r7, 0
- beq check_is_executing
-
- /* We have a new heir */
-
- /* Clear the thread dispatch necessary flag */
- li r7, 0
- stb r7, PER_CPU_DISPATCH_NEEDED(r6)
- msync
+ /* We may have a new heir */
/* Read the executing and heir */
lwz r7, PER_CPU_OFFSET_EXECUTING(r6)
lwz r8, PER_CPU_OFFSET_HEIR(r6)
+ /*
+ * Update the executing only if necessary to avoid cache line
+ * monopolization.
+ */
+ cmpw r7, r8
+ beq check_is_executing
+
/* Calculate the heir context pointer */
sub r7, r4, r7
add r4, r8, r7