From 258ad71e9626c16f30b40e06c321326636c976ff Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 25 Sep 2015 14:34:24 +0200 Subject: 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. --- cpukit/score/cpu/arm/cpu_asm.S | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'cpukit/score/cpu/arm/cpu_asm.S') diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S index 344512b395..6ee9e7418f 100644 --- a/cpukit/score/cpu/arm/cpu_asm.S +++ b/cpukit/score/cpu/arm/cpu_asm.S @@ -19,7 +19,7 @@ * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * - * Copyright (c) 2013-2014 embedded brains GmbH + * Copyright (c) 2013-2015 embedded brains GmbH * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -80,13 +80,13 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch) add r3, r1, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET ldrexb r4, [r3] cmp r4, #0 - bne .L_check_thread_dispatch_necessary + bne .L_get_potential_new_heir /* Try to update the is executing indicator of the heir context */ mov r4, #1 strexb r5, r4, [r3] cmp r5, #0 - bne .L_check_thread_dispatch_necessary + bne .L_get_potential_new_heir dmb #endif @@ -126,26 +126,23 @@ DEFINE_FUNCTION_ARM(_CPU_Context_restore) b .L_restore #ifdef RTEMS_SMP -.L_check_thread_dispatch_necessary: +.L_get_potential_new_heir: GET_SELF_CPU_CONTROL r2, r3 - /* Check if a thread dispatch is necessary */ - ldrb r4, [r2, #PER_CPU_DISPATCH_NEEDED] - cmp r4, #0 - beq .L_check_is_executing - - /* We have a new heir */ - - /* Clear the thread dispatch necessary flag */ - mov r4, #0 - strb r4, [r2, #PER_CPU_DISPATCH_NEEDED] - dmb + /* We may have a new heir */ /* Read the executing and heir */ ldr r4, [r2, #PER_CPU_OFFSET_EXECUTING] ldr r5, [r2, #PER_CPU_OFFSET_HEIR] + /* + * Update the executing only if necessary to avoid cache line + * monopolization. + */ + cmp r4, r5 + beq .L_check_is_executing + /* Calculate the heir context pointer */ sub r4, r1, r4 add r1, r5, r4 -- cgit v1.2.3