diff options
| author | Frédéric Desbiens <[email protected]> | 2026-10-02 10:42:44 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-10-02 10:42:44 -0400 |
| commit | 93387b0a60382a29579bbad5045c68328e3751df (patch) | |
| tree | 42be790d602cb76f55090e5a7c418df7ea2b3428 /ports/linux/gnu/src | |
| parent | 44d7c95c582d415c4ad84527180b29c93c3bf664 (diff) | |
| parent | 28281cd5647d4671236ca08d19bd18ed15b2265a (diff) | |
Merge pull request #783 from eclipse-threadx/devv6.5.2.202603_rel
Merged changes ahead of the v6.5.2.202603 release
Diffstat (limited to 'ports/linux/gnu/src')
| -rw-r--r-- | ports/linux/gnu/src/tx_thread_schedule.c | 45 | ||||
| -rw-r--r-- | ports/linux/gnu/src/tx_thread_stack_build.c | 12 |
2 files changed, 55 insertions, 2 deletions
diff --git a/ports/linux/gnu/src/tx_thread_schedule.c b/ports/linux/gnu/src/tx_thread_schedule.c index eeff680f..405ef4b8 100644 --- a/ports/linux/gnu/src/tx_thread_schedule.c +++ b/ports/linux/gnu/src/tx_thread_schedule.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -201,6 +203,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; diff --git a/ports/linux/gnu/src/tx_thread_stack_build.c b/ports/linux/gnu/src/tx_thread_stack_build.c index cdadba6c..102ded32 100644 --- a/ports/linux/gnu/src/tx_thread_stack_build.c +++ b/ports/linux/gnu/src/tx_thread_stack_build.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -79,6 +81,7 @@ void *_tx_linux_thread_entry(void *ptr); /**************************************************************************/ VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) { +ALIGN_TYPE fake_stack_ptr; struct sched_param sp; (VOID)function_ptr; @@ -118,8 +121,13 @@ struct sched_param sp; tx_interrupt_control nesting. */ thread_ptr -> tx_thread_linux_int_disabled_flag = 0; - /* Setup a fake thread stack pointer. */ - thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8); + /* Setup a fake thread stack pointer. The stack end points at the last byte of the + thread's stack area and is therefore not necessarily aligned, so round the result + down to a ULONG boundary. This pointer is dereferenced as a ULONG below and is + also the starting value of the stack checking logic's highest used pointer. */ + fake_stack_ptr = (ALIGN_TYPE) ((VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8)); + fake_stack_ptr = fake_stack_ptr & (~((ALIGN_TYPE) (sizeof(ULONG) - 1))); + thread_ptr -> tx_thread_stack_ptr = (VOID *) ((ALIGN_TYPE) fake_stack_ptr); /* Clear the first word of the stack. */ *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0; |
