summaryrefslogtreecommitdiff
path: root/ports/linux/gnu/inc
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2026-10-14 10:57:14 -0400
committerFrédéric Desbiens <[email protected]>2026-10-14 10:57:14 -0400
commitb017aea7e4e8a3e3d81fc110a5b815af754438eb (patch)
tree7b7a51cba70c049d740e900af85795cc8f97472d /ports/linux/gnu/inc
parent74d9e3937fa913380fdfdd902e528411c661ea3f (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.h13
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;