mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
Removed FIFO queueing from the ARMv7-A SMP ports so an ISR can no longer deadlock waiting for protection (#707)
The Cortex-A5, A7 and A9 SMP ports guarded the inter-core protection with a FIFO wait list: a core that could not take the lock added itself to a queue, incremented _tx_thread_smp_protect_wait_counts[core], and only the core at the head of the queue was allowed to acquire. Two parts of that scheme require the waiting core to be interruptible. _tx_thread_smp_unprotect() refuses to release the protection while the releasing core's own wait count is non-zero, and a queued core is taken back out of the list by _tx_thread_context_restore() when it is preempted. Neither can happen on a core that is spinning inside an ISR with interrupts already masked, because the spin loop restores the caller's interrupt posture rather than enabling interrupts. The core stays in the list forever and the system deadlocks with cores stuck in the wait loop. This is the deadlock Microsoft removed from the ARMv8-A SMP ports in 6.1.11, by dropping the wait list and using a plain LDAXR/STXR spinlock. The same removal was announced for the ARMv7-A ports at the time but was never made, so those three ports have carried the deadlock ever since. The FIFO queueing is now removed from the ARMv7-A SMP ports as well. _tx_thread_smp_protect() becomes an LDREX/STREX spinlock that releases interrupts between attempts, matching the sequence already used by the Cortex-R8 SMP port; _tx_thread_smp_unprotect() no longer consults the wait counts; and _tx_thread_context_restore() no longer has to unqueue a preempted core. The now unreferenced wait list macro headers are deleted. Verified by assembling all three GNU ports with arm-none-eabi-gcc for cortex-a5, cortex-a7 and cortex-a9, with and without TX_ENABLE_FIQ_SUPPORT, TX_ENABLE_WFE and TX_MPCORE_DEBUG_ENABLE, and by reading back the disassembly of the new protect sequence. The port consistency checks pass. Fixes #219 Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -29,8 +31,6 @@
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
|
||||
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_timer_interrupt_active
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
IMPORT _tx_thread_smp_protect_wait_list
|
||||
IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
IMPORT _tx_thread_smp_protect_wait_list_tail
|
||||
IMPORT _tx_thread_smp_protect_wait_list_size
|
||||
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
IMPORT _tx_execution_isr_exit
|
||||
ENDIF
|
||||
@@ -196,77 +191,6 @@ __tx_thread_no_preempt_restore
|
||||
; {
|
||||
;
|
||||
__tx_thread_preempt_restore
|
||||
;
|
||||
; /* Was the thread being preempted waiting for the lock? */
|
||||
; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
|
||||
;
|
||||
; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
LDR r2, [r1, #8] ; Pickup the owning core
|
||||
CMP r10, r2 ; Compare our core to the owning core
|
||||
BEQ _this_core_has_lock ; Do we have the lock?
|
||||
;
|
||||
; /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
; _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
;
|
||||
MOV r0, r10 ; Move the core ID to r0 for the macro
|
||||
macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock ; Leave
|
||||
;
|
||||
; }
|
||||
; else
|
||||
; {
|
||||
; /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
; never released it because it saw that there was someone waiting.
|
||||
; Note this core is not in the list. */
|
||||
;
|
||||
_this_core_has_lock
|
||||
;
|
||||
; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
; _tx_thread_smp_protect_wait_counts[core]--;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] ; Store new waiting value
|
||||
;
|
||||
; /* Now release the inter-core lock. */
|
||||
;
|
||||
; /* Set protected core as invalid. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF ; Build invalid value
|
||||
STR r2, [r1, #8] ; Mark the protected core as invalid
|
||||
DMB ; Ensure that accesses to shared resource have completed
|
||||
;
|
||||
; /* Release protection. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
;
|
||||
MOV r2, #0 ; Build release protection value
|
||||
STR r2, [r1, #0] ; Release the protection
|
||||
DSB ISH ; To ensure update of the protection occurs before other CPUs awake
|
||||
;
|
||||
; /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_WFE
|
||||
SEV ; Send event to other CPUs
|
||||
ENDIF
|
||||
;
|
||||
; }
|
||||
; }
|
||||
;
|
||||
|
||||
_nobody_waiting_for_lock
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
|
||||
MOV r1, lr ; Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
IMPORT _tx_thread_current_ptr
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
|
||||
AREA ||.text||, CODE, READONLY
|
||||
PRESERVE8
|
||||
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
|
||||
CMP r3, #0 ; Is the preempt disable flag set?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
|
||||
CMP r3, #0 ; Are any entities on this core waiting?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF ; Build invalid value
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -29,8 +31,6 @@
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
@/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ & FIQ interrupts
|
||||
@@ -51,11 +51,6 @@ SVC_MODE = 0x93 @ SVC mode
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_timer_interrupt_active
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
.global _tx_thread_smp_protect_wait_list
|
||||
.global _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
.global _tx_thread_smp_protect_wait_list_tail
|
||||
.global _tx_thread_smp_protect_wait_list_size
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
.global _tx_execution_isr_exit
|
||||
#endif
|
||||
@@ -198,77 +193,6 @@ __tx_thread_no_preempt_restore:
|
||||
@ {
|
||||
@
|
||||
__tx_thread_preempt_restore:
|
||||
@
|
||||
@ /* Was the thread being preempted waiting for the lock? */
|
||||
@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
|
||||
@
|
||||
@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
LDR r2, [r1, #8] @ Pickup the owning core
|
||||
CMP r10, r2 @ Compare our core to the owning core
|
||||
BEQ _this_core_has_lock @ Do we have the lock?
|
||||
@
|
||||
@ /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
@ _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
@
|
||||
MOV r0, r10 @ Move the core ID to r0 for the macro
|
||||
_tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock @ Leave
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@ /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
@ never released it because it saw that there was someone waiting.
|
||||
@ Note this core is not in the list. */
|
||||
@
|
||||
_this_core_has_lock:
|
||||
@
|
||||
@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
@ _tx_thread_smp_protect_wait_counts[core]--;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] @ Store new waiting value
|
||||
@
|
||||
@ /* Now release the inter-core lock. */
|
||||
@
|
||||
@ /* Set protected core as invalid. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF @ Build invalid value
|
||||
STR r2, [r1, #8] @ Mark the protected core as invalid
|
||||
DMB @ Ensure that accesses to shared resource have completed
|
||||
@
|
||||
@ /* Release protection. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
@
|
||||
MOV r2, #0 @ Build release protection value
|
||||
STR r2, [r1, #0] @ Release the protection
|
||||
DSB ISH @ To ensure update of the protection occurs before other CPUs awake
|
||||
@
|
||||
@ /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
@
|
||||
#ifdef TX_ENABLE_WFE
|
||||
SEV @ Send event to other CPUs
|
||||
#endif
|
||||
@
|
||||
@ }
|
||||
@ }
|
||||
@
|
||||
|
||||
_nobody_waiting_for_lock:
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
|
||||
MOV r1, lr @ Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
|
||||
.arm
|
||||
.text
|
||||
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
|
||||
CMP r3, #0 @ Is the preempt disable flag set?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
|
||||
CMP r3, #0 @ Are any entities on this core waiting?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF @ Build invalid value
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -29,8 +31,6 @@
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
|
||||
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_timer_interrupt_active
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
IMPORT _tx_thread_smp_protect_wait_list
|
||||
IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
IMPORT _tx_thread_smp_protect_wait_list_tail
|
||||
IMPORT _tx_thread_smp_protect_wait_list_size
|
||||
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
IMPORT _tx_execution_isr_exit
|
||||
ENDIF
|
||||
@@ -195,76 +190,6 @@ __tx_thread_no_preempt_restore
|
||||
; else
|
||||
; {
|
||||
__tx_thread_preempt_restore
|
||||
;
|
||||
; /* Was the thread being preempted waiting for the lock? */
|
||||
; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
|
||||
;
|
||||
; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
LDR r2, [r1, #8] ; Pickup the owning core
|
||||
CMP r10, r2 ; Compare our core to the owning core
|
||||
BEQ _this_core_has_lock ; Do we have the lock?
|
||||
;
|
||||
; /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
; _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
;
|
||||
macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock ; Leave
|
||||
;
|
||||
; }
|
||||
; else
|
||||
; {
|
||||
; /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
; never released it because it saw that there was someone waiting.
|
||||
; Note this core is not in the list. */
|
||||
;
|
||||
_this_core_has_lock
|
||||
;
|
||||
; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
; _tx_thread_smp_protect_wait_counts[core]--;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] ; Store new waiting value
|
||||
;
|
||||
; /* Now release the inter-core lock. */
|
||||
;
|
||||
; /* Set protected core as invalid. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF ; Build invalid value
|
||||
STR r2, [r1, #8] ; Mark the protected core as invalid
|
||||
DMB ; Ensure that accesses to shared resource have completed
|
||||
;
|
||||
; /* Release protection. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
;
|
||||
MOV r2, #0 ; Build release protection value
|
||||
STR r2, [r1, #0] ; Release the protection
|
||||
DSB ISH ; To ensure update of the protection occurs before other CPUs awake
|
||||
;
|
||||
; /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_WFE
|
||||
SEV ; Send event to other CPUs
|
||||
ENDIF
|
||||
;
|
||||
; }
|
||||
; }
|
||||
;
|
||||
|
||||
_nobody_waiting_for_lock
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
|
||||
MOV r1, lr ; Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
IMPORT _tx_thread_current_ptr
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
|
||||
AREA ||.text||, CODE, READONLY
|
||||
PRESERVE8
|
||||
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
|
||||
CMP r3, #0 ; Is the preempt disable flag set?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
|
||||
CMP r3, #0 ; Are any entities on this core waiting?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF ; Build invalid value
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -28,8 +30,6 @@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
.arm
|
||||
|
||||
@@ -50,11 +50,6 @@ IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_timer_interrupt_active
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
.global _tx_thread_smp_protect_wait_list
|
||||
.global _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
.global _tx_thread_smp_protect_wait_list_tail
|
||||
.global _tx_thread_smp_protect_wait_list_size
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
.global _tx_execution_isr_exit
|
||||
#endif
|
||||
@@ -200,76 +195,6 @@ __tx_thread_no_preempt_restore:
|
||||
@ else
|
||||
@ {
|
||||
__tx_thread_preempt_restore:
|
||||
@
|
||||
@ /* Was the thread being preempted waiting for the lock? */
|
||||
@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
|
||||
@
|
||||
@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
LDR r2, [r1, #8] @ Pickup the owning core
|
||||
CMP r10, r2 @ Compare our core to the owning core
|
||||
BEQ _this_core_has_lock @ Do we have the lock?
|
||||
@
|
||||
@ /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
@ _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
@
|
||||
_tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock @ Leave
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@ /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
@ never released it because it saw that there was someone waiting.
|
||||
@ Note this core is not in the list. */
|
||||
@
|
||||
_this_core_has_lock:
|
||||
@
|
||||
@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
@ _tx_thread_smp_protect_wait_counts[core]--;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] @ Store new waiting value
|
||||
@
|
||||
@ /* Now release the inter-core lock. */
|
||||
@
|
||||
@ /* Set protected core as invalid. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF @ Build invalid value
|
||||
STR r2, [r1, #8] @ Mark the protected core as invalid
|
||||
DMB @ Ensure that accesses to shared resource have completed
|
||||
@
|
||||
@ /* Release protection. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
@
|
||||
MOV r2, #0 @ Build release protection value
|
||||
STR r2, [r1, #0] @ Release the protection
|
||||
DSB ISH @ To ensure update of the protection occurs before other CPUs awake
|
||||
@
|
||||
@ /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
@
|
||||
#ifdef TX_ENABLE_WFE
|
||||
SEV @ Send event to other CPUs
|
||||
#endif
|
||||
@
|
||||
@ }
|
||||
@ }
|
||||
@
|
||||
|
||||
_nobody_waiting_for_lock:
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
|
||||
MOV r1, lr @ Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
|
||||
.arm
|
||||
.text
|
||||
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
|
||||
CMP r3, #0 @ Is the preempt disable flag set?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
|
||||
CMP r3, #0 @ Are any entities on this core waiting?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF @ Build invalid value
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -29,8 +31,6 @@
|
||||
;#include "tx_thread.h"
|
||||
;#include "tx_timer.h"
|
||||
;
|
||||
;/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
|
||||
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_timer_interrupt_active
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
IMPORT _tx_thread_smp_protect_wait_list
|
||||
IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
IMPORT _tx_thread_smp_protect_wait_list_tail
|
||||
IMPORT _tx_thread_smp_protect_wait_list_size
|
||||
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
IMPORT _tx_execution_isr_exit
|
||||
ENDIF
|
||||
@@ -196,77 +191,6 @@ __tx_thread_no_preempt_restore
|
||||
; {
|
||||
;
|
||||
__tx_thread_preempt_restore
|
||||
;
|
||||
; /* Was the thread being preempted waiting for the lock? */
|
||||
; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
|
||||
;
|
||||
; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
; {
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
LDR r2, [r1, #8] ; Pickup the owning core
|
||||
CMP r10, r2 ; Compare our core to the owning core
|
||||
BEQ _this_core_has_lock ; Do we have the lock?
|
||||
;
|
||||
; /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
; _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
;
|
||||
MOV r0, r10 ; Move the core ID to r0 for the macro
|
||||
macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock ; Leave
|
||||
;
|
||||
; }
|
||||
; else
|
||||
; {
|
||||
; /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
; never released it because it saw that there was someone waiting.
|
||||
; Note this core is not in the list. */
|
||||
;
|
||||
_this_core_has_lock
|
||||
;
|
||||
; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
; _tx_thread_smp_protect_wait_counts[core]--;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
|
||||
SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] ; Store new waiting value
|
||||
;
|
||||
; /* Now release the inter-core lock. */
|
||||
;
|
||||
; /* Set protected core as invalid. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
;
|
||||
LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF ; Build invalid value
|
||||
STR r2, [r1, #8] ; Mark the protected core as invalid
|
||||
DMB ; Ensure that accesses to shared resource have completed
|
||||
;
|
||||
; /* Release protection. */
|
||||
; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
;
|
||||
MOV r2, #0 ; Build release protection value
|
||||
STR r2, [r1, #0] ; Release the protection
|
||||
DSB ISH ; To ensure update of the protection occurs before other CPUs awake
|
||||
;
|
||||
; /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_WFE
|
||||
SEV ; Send event to other CPUs
|
||||
ENDIF
|
||||
;
|
||||
; }
|
||||
; }
|
||||
;
|
||||
|
||||
_nobody_waiting_for_lock
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
|
||||
MOV r1, lr ; Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
;/***************************************************************************
|
||||
; * Copyright (c) 2024 Microsoft Corporation
|
||||
; * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
; *
|
||||
; * This program and the accompanying materials are made available under the
|
||||
; * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; **************************************************************************/
|
||||
; Some portions generated by Copilot (Opus 5).
|
||||
;
|
||||
;
|
||||
;/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
IMPORT _tx_thread_current_ptr
|
||||
IMPORT _tx_thread_smp_protection
|
||||
IMPORT _tx_thread_preempt_disable
|
||||
IMPORT _tx_thread_smp_protect_wait_counts
|
||||
|
||||
AREA ||.text||, CODE, READONLY
|
||||
PRESERVE8
|
||||
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
|
||||
CMP r3, #0 ; Is the preempt disable flag set?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
|
||||
CMP r3, #0 ; Are any entities on this core waiting?
|
||||
BNE _still_protected ; Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF ; Build invalid value
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -29,8 +31,6 @@
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
@/* Include macros for modifying the wait list. */
|
||||
#include "tx_thread_smp_protection_wait_list_macros.h"
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ & FIQ interrupts
|
||||
@@ -51,11 +51,6 @@ SVC_MODE = 0x93 @ SVC mode
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_timer_interrupt_active
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
.global _tx_thread_smp_protect_wait_list
|
||||
.global _tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
.global _tx_thread_smp_protect_wait_list_tail
|
||||
.global _tx_thread_smp_protect_wait_list_size
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
.global _tx_execution_isr_exit
|
||||
#endif
|
||||
@@ -198,77 +193,6 @@ __tx_thread_no_preempt_restore:
|
||||
@ {
|
||||
@
|
||||
__tx_thread_preempt_restore:
|
||||
@
|
||||
@ /* Was the thread being preempted waiting for the lock? */
|
||||
@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
CMP r2, #0
|
||||
BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
|
||||
@
|
||||
@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
|
||||
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
LDR r2, [r1, #8] @ Pickup the owning core
|
||||
CMP r10, r2 @ Compare our core to the owning core
|
||||
BEQ _this_core_has_lock @ Do we have the lock?
|
||||
@
|
||||
@ /* We don't have the lock. This core should be in the list. Remove it. */
|
||||
@ _tx_thread_smp_protect_wait_list_remove(this_core);
|
||||
@
|
||||
MOV r0, r10 @ Move the core ID to r0 for the macro
|
||||
_tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
|
||||
B _nobody_waiting_for_lock @ Leave
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@ /* We have the lock. This means the ISR got the inter-core lock, but
|
||||
@ never released it because it saw that there was someone waiting.
|
||||
@ Note this core is not in the list. */
|
||||
@
|
||||
_this_core_has_lock:
|
||||
@
|
||||
@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
|
||||
@ _tx_thread_smp_protect_wait_counts[core]--;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
|
||||
LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
|
||||
SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
|
||||
STR r2, [r1, r10, LSL #2] @ Store new waiting value
|
||||
@
|
||||
@ /* Now release the inter-core lock. */
|
||||
@
|
||||
@ /* Set protected core as invalid. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
|
||||
@
|
||||
LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
|
||||
MOV r2, #0xFFFFFFFF @ Build invalid value
|
||||
STR r2, [r1, #8] @ Mark the protected core as invalid
|
||||
DMB @ Ensure that accesses to shared resource have completed
|
||||
@
|
||||
@ /* Release protection. */
|
||||
@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
|
||||
@
|
||||
MOV r2, #0 @ Build release protection value
|
||||
STR r2, [r1, #0] @ Release the protection
|
||||
DSB ISH @ To ensure update of the protection occurs before other CPUs awake
|
||||
@
|
||||
@ /* Wake up waiting processors. Note interrupts are already enabled. */
|
||||
@
|
||||
#ifdef TX_ENABLE_WFE
|
||||
SEV @ Send event to other CPUs
|
||||
#endif
|
||||
@
|
||||
@ }
|
||||
@ }
|
||||
@
|
||||
|
||||
_nobody_waiting_for_lock:
|
||||
|
||||
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
|
||||
MOV r1, lr @ Save lr (point of interrupt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
@/***************************************************************************
|
||||
@ * Copyright (c) 2024 Microsoft Corporation
|
||||
@ * Copyright (c) 2026 Eclipse ThreadX contributors
|
||||
@ *
|
||||
@ * This program and the accompanying materials are made available under the
|
||||
@ * terms of the MIT License which is available at
|
||||
@@ -7,6 +8,7 @@
|
||||
@ *
|
||||
@ * SPDX-License-Identifier: MIT
|
||||
@ **************************************************************************/
|
||||
@ Some portions generated by Copilot (Opus 5).
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@@ -33,7 +35,6 @@
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_smp_protection
|
||||
.global _tx_thread_preempt_disable
|
||||
.global _tx_thread_smp_protect_wait_counts
|
||||
|
||||
.arm
|
||||
.text
|
||||
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
|
||||
CMP r3, #0 @ Is the preempt disable flag set?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
|
||||
LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
|
||||
CMP r3, #0 @ Are any entities on this core waiting?
|
||||
BNE _still_protected @ Yes, skip the protection release
|
||||
|
||||
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
|
||||
MOV r3, #0xFFFFFFFF @ Build invalid value
|
||||
|
||||
Reference in New Issue
Block a user