diff options
| author | Frédéric Desbiens <[email protected]> | 2026-10-14 10:57:14 -0400 |
|---|---|---|
| committer | Frédéric Desbiens <[email protected]> | 2026-10-14 10:57:14 -0400 |
| commit | b017aea7e4e8a3e3d81fc110a5b815af754438eb (patch) | |
| tree | 7b7a51cba70c049d740e900af85795cc8f97472d /ports/linux/gnu/inc | |
| parent | 74d9e3937fa913380fdfdd902e528411c661ea3f (diff) | |
Restored the Linux port mutex retryv6.4.1_cert
This was reverted because a NetX Secure regression test segfaulted with it
in place. The cause was the test: it hands the certificate verify path a
stack-local certificate whose signature it never assigns, and this change
moves the stack layout that decides whether the unassigned slot reads null
or a readable leftover. That test has been fixed, so the retry comes back.
Measured with the test unfixed and this change in place, on a layout built
without the stack protector: eight of eight runs segfault, the fault read
from the faulting process as a null signature dereferenced by the ECDSA
verify. With the test fixed, nineteen build configurations run it eight
times each with no fault.
Without this change, a thread signalled into the port's suspend handler
never returns to the contended-mutex loop, the next unlock's wake-up is
lost, the scheduler is left parked, and the timer interrupt never runs --
which stalls the tick and hangs about 0.39% of instances of a few TCP
tests for their full timeout.
Diffstat (limited to 'ports/linux/gnu/inc')
| -rw-r--r-- | ports/linux/gnu/inc/tx_port.h | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/ports/linux/gnu/inc/tx_port.h b/ports/linux/gnu/inc/tx_port.h index dc39b5f9..70a9fb9d 100644 --- a/ports/linux/gnu/inc/tx_port.h +++ b/ports/linux/gnu/inc/tx_port.h @@ -525,7 +525,7 @@ VOID _tx_thread_interrupt_restore(UINT previous_posture); #define TX_RESTORE _tx_linux_debug_entry_insert("RESTORE", __FILE__, __LINE__); \ _tx_thread_interrupt_restore(tx_saved_posture); #endif /* TX_LINUX_DEBUG_ENABLE */ -#define tx_linux_mutex_lock(p) pthread_mutex_lock(&p) +#define tx_linux_mutex_lock(p) _tx_linux_mutex_lock_retry(&p) #define tx_linux_mutex_unlock(p) pthread_mutex_unlock(&p) #define tx_linux_mutex_recursive_unlock(p) {\ int _recursive_count = (int)tx_linux_mutex_recursive_count;\ @@ -566,6 +566,17 @@ extern CHAR _tx_version_id[]; /* Define externals for the Linux port of ThreadX. */ extern pthread_mutex_t _tx_linux_mutex; + +/* Define how long a thread waits on the Linux mutex before retrying. A thread + parked on the mutex can be suspended by the port's signal handler and so never + act on the wake-up the next unlock sends it, which leaves the wake-up lost and + every other waiter parked on a mutex that is free. */ + +#ifndef TX_LINUX_MUTEX_RETRY_NSEC +#define TX_LINUX_MUTEX_RETRY_NSEC 1000000 +#endif + +void _tx_linux_mutex_lock_retry(pthread_mutex_t *mutex); extern sem_t _tx_linux_semaphore; extern sem_t _tx_linux_semaphore_no_idle; extern ULONG _tx_linux_global_int_disabled_flag; |
