Skip to content

Commit 6c45adf

Browse files
committed
Fix race condition and message loss in Cortex-M AC6 ports (#516)
- Added compiler memory barriers to BASEPRI management functions in tx_port.h. - Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.S to prevent fall-through before context switch. - These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled. Assisted-by: Gemini (Gemini 2.0 Flash)
1 parent c05ba69 commit 6c45adf

File tree

6 files changed

+46
-10
lines changed

6 files changed

+46
-10
lines changed

ports/cortex_m3/ac6/inc/tx_port.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -539,20 +541,20 @@ unsigned int posture;
539541
#ifdef TX_PORT_USE_BASEPRI
540542
__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value)
541543
{
542-
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
544+
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory");
543545
}
544-
#else
546+
#endif
547+
545548
__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
546549
{
547550
__asm__ volatile ("CPSIE i": : : "memory");
548551
}
549-
#endif
550552

551553
__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture)
552554
{
553555
#ifdef TX_PORT_USE_BASEPRI
554556
__set_basepri_value(int_posture);
555-
//__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory");
557+
__asm__ volatile ("" : : : "memory");
556558
#else
557559
__asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
558560
#endif
@@ -578,6 +580,7 @@ unsigned int interrupt_save;
578580

579581
/* Set PendSV to invoke ThreadX scheduler. */
580582
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
583+
__asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory");
581584
if (__get_ipsr_value() == 0)
582585
{
583586
interrupt_save = __get_interrupt_posture();
@@ -589,7 +592,6 @@ unsigned int interrupt_save;
589592
__restore_interrupt(interrupt_save);
590593
}
591594
}
592-
593595
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
594596
#define TX_DISABLE interrupt_save = __disable_interrupts();
595597
#define TX_RESTORE __restore_interrupt(interrupt_save);

ports/cortex_m3/ac6/src/tx_thread_system_return.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -73,6 +75,8 @@ _tx_thread_system_return:
7375
MOV r0, #0x10000000 // Load PENDSVSET bit
7476
MOV r1, #0xE000E000 // Load NVIC base
7577
STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR
78+
DSB #0xF // Ensure memory access is complete
79+
ISB #0xF // Flush pipeline
7680
MRS r0, IPSR // Pickup IPSR
7781
CMP r0, #0 // Is it a thread returning?
7882
BNE _isr_context // If ISR, skip interrupt enable

ports/cortex_m33/ac6/inc/tx_port.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -541,7 +543,7 @@ UINT posture;
541543
#ifdef TX_PORT_USE_BASEPRI
542544
__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value)
543545
{
544-
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
546+
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory");
545547
}
546548
#else
547549
__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
@@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i
554556
{
555557
#ifdef TX_PORT_USE_BASEPRI
556558
__set_basepri_value(int_posture);
559+
__asm__ volatile ("" : : : "memory");
557560
#else
558561
__asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
559562
#endif
@@ -579,6 +582,7 @@ UINT interrupt_save;
579582

580583
/* Set PendSV to invoke ThreadX scheduler. */
581584
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
585+
__asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory");
582586
if (_tx_ipsr_get() == 0)
583587
{
584588
interrupt_save = __get_interrupt_posture();

ports/cortex_m33/ac6/src/tx_thread_system_return.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -74,6 +76,8 @@ _tx_thread_system_return:
7476
MOV r0, #0x10000000 // Load PENDSVSET bit
7577
MOV r1, #0xE000E000 // Load NVIC base
7678
STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR
79+
DSB #0xF // Ensure memory access is complete
80+
ISB #0xF // Flush pipeline
7781
MRS r0, IPSR // Pickup IPSR
7882
CMP r0, #0 // Is it a thread returning?
7983
BNE _isr_context // If ISR, skip interrupt enable

ports/cortex_m4/ac6/inc/tx_port.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -539,20 +541,20 @@ unsigned int posture;
539541
#ifdef TX_PORT_USE_BASEPRI
540542
__attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value)
541543
{
542-
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value));
544+
__asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory");
543545
}
544-
#else
546+
#endif
547+
545548
__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
546549
{
547550
__asm__ volatile ("CPSIE i": : : "memory");
548551
}
549-
#endif
550552

551553
__attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture)
552554
{
553555
#ifdef TX_PORT_USE_BASEPRI
554556
__set_basepri_value(int_posture);
555-
//__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory");
557+
__asm__ volatile ("" : : : "memory");
556558
#else
557559
__asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory");
558560
#endif
@@ -574,6 +576,22 @@ unsigned int int_posture;
574576

575577
__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
576578
{
579+
unsigned int interrupt_save;
580+
581+
/* Set PendSV to invoke ThreadX scheduler. */
582+
*((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
583+
__asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory");
584+
if (__get_ipsr_value() == 0)
585+
{
586+
interrupt_save = __get_interrupt_posture();
587+
#ifdef TX_PORT_USE_BASEPRI
588+
__set_basepri_value(0);
589+
#else
590+
__enable_interrupts();
591+
#endif
592+
__restore_interrupt(interrupt_save);
593+
}
594+
}
577595
unsigned int interrupt_save;
578596

579597
/* Set PendSV to invoke ThreadX scheduler. */

ports/cortex_m4/ac6/src/tx_thread_system_return.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* SPDX-License-Identifier: MIT
1010
**************************************************************************/
1111

12+
// Some portions generated by Gemini (Gemini 2.0 Flash).
13+
1214

1315
/**************************************************************************/
1416
/**************************************************************************/
@@ -73,6 +75,8 @@ _tx_thread_system_return:
7375
MOV r0, #0x10000000 // Load PENDSVSET bit
7476
MOV r1, #0xE000E000 // Load NVIC base
7577
STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR
78+
DSB #0xF // Ensure memory access is complete
79+
ISB #0xF // Flush pipeline
7680
MRS r0, IPSR // Pickup IPSR
7781
CMP r0, #0 // Is it a thread returning?
7882
BNE _isr_context // If ISR, skip interrupt enable

0 commit comments

Comments
 (0)