Conversation
This is the ThreadX half of the defect fixed for ThreadX SMP in an earlier pull request. The Linux port suspends a thread with a signal whose handler calls sigsuspend and does not return until the thread is resumed, and it takes its critical section with a bare pthread_mutex_lock through tx_linux_mutex_lock. A thread can therefore be signalled while it is parked on _tx_linux_mutex. glibc waits for a contended mutex in a loop that re-arms the futex wait after a signal, and this handler never returns to it. The next unlock hands its wake-up to that thread, which will not act on it, and any other thread parked on the mutex is never woken, leaving the mutex free with waiters on it. tx_linux_mutex_lock now calls a helper that waits with pthread_mutex_timedlock and retries, so the wait is re-armed every TX_LINUX_MUTEX_RETRY_NSEC and a lost wake-up costs one retry period instead of the process. The period is one millisecond. pthread_mutex_timedlock needs _GNU_SOURCE under -std=c99, which both of this port's build systems already define. These are the only two ports affected: a sigsuspend-based suspend handler exists in the Linux and SMP Linux ports and nowhere else, and those two are also the only ports taking a critical section with pthread_mutex_lock. Unlike the SMP port, this one has never been observed to deadlock, which is consistent with one emulated core and far less suspend and resume traffic. The fix is by inspection, and verified as breaking nothing: all seven configurations pass with retries disabled, 105/105 in five and 100/100 in two. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #752. This is the ThreadX half of what #753 fixes for ThreadX SMP.
The Linux port has both halves of the same defect. Its suspend handler in
ports/linux/gnu/src/tx_initialize_low_level.ccallssigsuspendand does not return until the thread is resumed, andtx_linux_mutex_lockinports/linux/gnu/inc/tx_port.his a barepthread_mutex_lock. A thread can therefore be signalled while it is parked on_tx_linux_mutex; glibc waits for a contended mutex in a loop that re-arms the futex wait after a signal, and this handler never returns to it, so the next unlock hands its wake-up to a thread that will not act on it and any other waiter is left on a mutex that reads free. #752 has the captures of that state from the SMP port.tx_linux_mutex_locknow calls a helper that waits withpthread_mutex_timedlockand retries, so the wait is re-armed everyTX_LINUX_MUTEX_RETRY_NSEC— one millisecond — and a lost wake-up costs a retry rather than the process. Nothing else changes; the hand-over path is untouched whenever the wake-up arrives.pthread_mutex_timedlockneeds_GNU_SOURCEunder-std=c99, andports/linux/gnu/CMakeLists.txtand the port's example Makefile both already define it.These are the only two ports affected. A
sigsuspend-based suspend handler exists inports/linux/gnuandports_smp/linux/gnuand nowhere else in the tree, and those two are also the only ports that take a critical section withpthread_mutex_lock. The Win32 ports use Windows primitives and are unaffected.What is different from #753, and worth being explicit about: this port has never been observed to deadlock. The ThreadX regression suite recorded no first-attempt failure across 105 configuration-runs with retries disabled, and none in any of the 33 CI runs dispatched while the SMP defect was being characterised — including the two whose SMP job failed. That is consistent with one emulated core and far less suspend and resume traffic, not with the code being different. So this is a fix by inspection rather than one driven by a reproduction, and it is offered as such.
What it is verified to do is break nothing: all seven build configurations pass with retries disabled and
CTEST_PARALLEL_LEVEL=1, 105/105 in five and 100/100 in two, 715 test executions.