summaryrefslogtreecommitdiff
path: root/ports/linux/gnu/src
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/src
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/src')
-rw-r--r--ports/linux/gnu/src/tx_thread_schedule.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/ports/linux/gnu/src/tx_thread_schedule.c b/ports/linux/gnu/src/tx_thread_schedule.c
index d65104a1..c66aa891 100644
--- a/ports/linux/gnu/src/tx_thread_schedule.c
+++ b/ports/linux/gnu/src/tx_thread_schedule.c
@@ -8,6 +8,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
+
/**************************************************************************/
/**************************************************************************/
@@ -206,6 +208,49 @@ struct timespec ts;
}
}
+/* Define the ThreadX Linux mutex lock function. The wait is timed and retried
+ rather than left to pthread_mutex_lock, because a thread can be signalled into
+ the port's suspend handler while it is parked on this mutex. That handler does
+ not return until the thread is resumed, so the wake-up the next unlock sends is
+ delivered to a thread that never retries and is lost. Any other thread parked
+ on the mutex then waits on a mutex that is free. Retrying on a timeout costs
+ nothing when the mutex is handed over normally, and turns that lost wake-up into
+ a delay of at most the retry period. */
+
+void _tx_linux_mutex_lock_retry(pthread_mutex_t *mutex)
+{
+
+INT linux_status;
+struct timespec ts;
+
+
+ do
+ {
+
+ /* Set the deadline for this attempt. */
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_nsec = ts.tv_nsec + TX_LINUX_MUTEX_RETRY_NSEC;
+ if (ts.tv_nsec >= 1000000000)
+ {
+
+ ts.tv_nsec = ts.tv_nsec - 1000000000;
+ ts.tv_sec++;
+ }
+
+ linux_status = pthread_mutex_timedlock(mutex, &ts);
+
+ /* Anything but the deadline expiring is a real failure to obtain the
+ mutex, so stop retrying. */
+ if ((linux_status != 0) && (linux_status != ETIMEDOUT))
+ {
+
+ break;
+ }
+
+ } while (linux_status != 0);
+}
+
+
void _tx_thread_delete_port_completion(TX_THREAD *thread_ptr, UINT tx_saved_posture)
{
INT linux_status;