Masked the SMP remap core maps to silence a false -O2 array bounds error (#728)

Fixes #469

`_tx_thread_smp_remap_solution_find` indexes `_tx_thread_smp_schedule_list` with
the lowest set bit of the core maps it is given. Every caller already masks
those maps with `TX_THREAD_SMP_CORE_MASK`, but the compiler cannot see it, so
when the function is inlined into `_tx_thread_system_suspend` at `-O2` GCC
assumes a bit number as high as 31 and reports an out-of-bounds subscript.
`-Werror` turns that into a build failure.

Masked the three incoming maps at the top of the function, in both the inline
version in `common_smp/inc/tx_thread.h` and the twin in
`tx_thread_smp_utilities.c`. The masks are semantic no-ops, so scheduling is
unchanged, but the range is now visible to the optimizer. The first core queue
entry is also initialized, because the narrowed range lets GCC consider an empty
queue and warn about that instead.

Reproduced on the Cortex-A9 SMP port with arm-none-eabi-gcc 13.2.1, and clean
afterwards across -O2, -O3 and -Os and 2, 4 and 8 core configurations. SMP suite
116/116.

Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
Frédéric Desbiens
2026-09-15 16:24:40 -04:00
committed by GitHub
parent 1d4a4aeec8
commit d15f28ab9f
2 changed files with 18 additions and 0 deletions
+9
View File
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -1171,6 +1172,11 @@ TX_THREAD *last_thread;
TX_THREAD *thread_remap_list[TX_THREAD_SMP_MAX_CORES];
/* Limit the supplied core maps to the cores that are actually present. */
available_cores = available_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
thread_possible_cores = thread_possible_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
test_possible_cores = test_possible_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
/* Clear the last thread cores in the search. */
last_thread_cores = ((ULONG) 0);
@@ -1181,6 +1187,9 @@ TX_THREAD *thread_remap_list[TX_THREAD_SMP_MAX_CORES];
queue_first = ((UINT) 0);
queue_last = ((UINT) 0);
/* Initialize the first core queue entry. */
core_queue[0] = ((UINT) 0);
/* Build a list of possible cores for this thread to execute on, starting
with the previously mapped core. */
core = schedule_thread -> tx_thread_smp_core_mapped;
+9
View File
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -654,6 +655,11 @@ TX_THREAD *last_thread;
TX_THREAD *thread_remap_list[TX_THREAD_SMP_MAX_CORES];
/* Limit the supplied core maps to the cores that are actually present. */
available_cores = available_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
thread_possible_cores = thread_possible_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
test_possible_cores = test_possible_cores & ((ULONG) TX_THREAD_SMP_CORE_MASK);
/* Clear the last thread cores in the search. */
last_thread_cores = ((ULONG) 0);
@@ -664,6 +670,9 @@ TX_THREAD *thread_remap_list[TX_THREAD_SMP_MAX_CORES];
queue_first = ((UINT) 0);
queue_last = ((UINT) 0);
/* Initialize the first core queue entry. */
core_queue[0] = ((UINT) 0);
/* Build a list of possible cores for this thread to execute on, starting
with the previously mapped core. */
core = schedule_thread -> tx_thread_smp_core_mapped;