Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/inc/tx_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ VOID _tx_mutex_initialize(VOID);

/* Define internal mutex management function prototypes. */

VOID _tx_mutex_priority_chain(TX_THREAD *thread_ptr);
VOID _tx_mutex_inherit_priority_update(TX_MUTEX *mutex_ptr);
VOID _tx_mutex_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
VOID _tx_mutex_thread_release(TX_THREAD *thread_ptr);
VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT new_priority);
Expand Down
2 changes: 2 additions & 0 deletions common/inc/tx_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ THREAD_DECLARE volatile UINT _tx_thread_preempt_disable;
termination. This pointer is setup during mutex initialization. */

THREAD_DECLARE VOID (*_tx_thread_mutex_release)(TX_THREAD *thread_ptr);
/* Optional mutex inheritance update, installed by mutex creation. */
THREAD_DECLARE VOID (*_tx_thread_mutex_priority_update)(TX_MUTEX *mutex_ptr);


/* Define the global build options variable. This contains a bit map representing
Expand Down
24 changes: 21 additions & 3 deletions common/inc/tx_user_sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

/* Portions of this file were generated with AI assistance. */


/**************************************************************************/
/**************************************************************************/
/** */
Expand Down Expand Up @@ -262,6 +259,27 @@
#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
*/

/* Enable bounded, bidirectional priority inheritance through mutex chains.
Define a nonnegative integer K to visit the first owner and at most K further
waiting-mutex edges (K + 1 distinct owners); zero retains a single owner.
Get, wait exit, waiter priority change, release and transfer use the same bound.
A non-inheriting mutex or inactive mutex wait ends the walk. Cycles wholly
contained in the visited path are recomputed from base priorities and outside
waiters, without retaining their own obsolete boosts. A cycle extending beyond
the bound can still retain an outside cached contribution; configure K to cover
the application's longest possible cycle if cycle restoration is required.
Work is O(N*N + N*W + M), for N <= K + 1 visited owners, W waiters and M owned
mutexes across those owners, plus up to N scheduler priority changes. All graph
processing holds interrupt/SMP protection with preemption disabled; the bound
alone does not bound list lengths or total interrupt latency. Stack scratch is
(K + 1)*(sizeof(TX_THREAD *) + 2*sizeof(UINT)), with no allocation or recursion.
When undefined, get retains its existing single-level path and restoration
scans only the changed waiter list and the first owner's cached mutex list. */

/*
#define TX_MUTEX_INHERIT_CHAIN_MAX 8
*/

/* Determine if queue performance gathering is required by the application. When the following is
defined, ThreadX gathers various queue performance information. */

Expand Down
13 changes: 13 additions & 0 deletions common/src/tx_mutex_cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ TX_THREAD *next_thread;
TX_THREAD *previous_thread;


#ifdef TX_NOT_INTERRUPTABLE
/* Suspension sequences are not used in the non-interruptable kernel. */
(VOID) suspension_sequence;
#endif

#ifndef TX_NOT_INTERRUPTABLE

/* Disable interrupts to remove the suspended thread from the mutex. */
Expand Down Expand Up @@ -155,6 +160,14 @@ TX_THREAD *previous_thread;
}
}

/* Remove this waiter's inheritance before it can resume. */
if (mutex_ptr -> tx_mutex_inherit == TX_TRUE)
{
_tx_thread_preempt_disable++;
_tx_mutex_inherit_priority_update(mutex_ptr);
_tx_thread_preempt_disable--;
}

/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP)
Expand Down
3 changes: 1 addition & 2 deletions common/src/tx_mutex_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

/* Portions of this file were generated with AI assistance. */


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -91,6 +89,7 @@ TX_MUTEX *previous_mutex;

/* Setup the thread mutex release function pointer. */
_tx_thread_mutex_release = &(_tx_mutex_thread_release);
_tx_thread_mutex_priority_update = &(_tx_mutex_inherit_priority_update);

/* Place the mutex on the list of created mutexes. First,
check for an empty list. */
Expand Down
35 changes: 35 additions & 0 deletions common/src/tx_mutex_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
/* _tx_thread_system_suspend Suspend thread service */
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
/* _tx_mutex_priority_change Inherit thread priority */
/* _tx_mutex_inherit_priority_update Recompute mutex inheritance */
/* */
/* CALLED BY */
/* */
Expand All @@ -74,7 +75,9 @@ TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_MUTEX *next_mutex;
TX_MUTEX *previous_mutex;
#if !defined(TX_MUTEX_INHERIT_CHAIN_MAX) || defined(TX_MUTEX_ENABLE_PERFORMANCE_INFO)
TX_THREAD *mutex_owner;
#endif
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
UINT status;
Expand Down Expand Up @@ -203,7 +206,9 @@ UINT status;
/* Prepare for suspension of this thread. */

/* Pickup the mutex owner. */
#if !defined(TX_MUTEX_INHERIT_CHAIN_MAX) || defined(TX_MUTEX_ENABLE_PERFORMANCE_INFO)
mutex_owner = mutex_ptr -> tx_mutex_owner;
#endif

#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO

Expand Down Expand Up @@ -284,6 +289,18 @@ UINT status;
owning the mutex. */
if (mutex_ptr -> tx_mutex_inherit == TX_TRUE)
{
#ifdef TX_MUTEX_INHERIT_CHAIN_MAX
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
if (mutex_owner -> tx_thread_priority > thread_ptr -> tx_thread_priority)
{
_tx_mutex_performance__priority_inheritance_count++;
mutex_ptr -> tx_mutex_performance__priority_inheritance_count++;
}
#endif
_tx_thread_preempt_disable++;
_tx_mutex_inherit_priority_update(mutex_ptr);
_tx_thread_preempt_disable--;
#else

/* Determine if this is the highest priority to raise for this mutex. */
if (mutex_ptr -> tx_mutex_highest_priority_waiting > thread_ptr -> tx_thread_priority)
Expand Down Expand Up @@ -318,6 +335,7 @@ UINT status;
mutex_ptr -> tx_mutex_performance__priority_inheritance_count++;
#endif
}
#endif
}

/* Call actual non-interruptable thread suspension routine. */
Expand All @@ -336,13 +354,25 @@ UINT status;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;

#ifndef TX_MUTEX_INHERIT_CHAIN_MAX
/* Restore interrupts. */
TX_RESTORE
#endif

/* Determine if we need to raise the priority of the thread
owning the mutex. */
if (mutex_ptr -> tx_mutex_inherit == TX_TRUE)
{
#ifdef TX_MUTEX_INHERIT_CHAIN_MAX
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
if (mutex_owner -> tx_thread_priority > thread_ptr -> tx_thread_priority)
{
_tx_mutex_performance__priority_inheritance_count++;
mutex_ptr -> tx_mutex_performance__priority_inheritance_count++;
}
#endif
_tx_mutex_inherit_priority_update(mutex_ptr);
#else

/* Determine if this is the highest priority to raise for this mutex. */
if (mutex_ptr -> tx_mutex_highest_priority_waiting > thread_ptr -> tx_thread_priority)
Expand Down Expand Up @@ -377,8 +407,13 @@ UINT status;
mutex_ptr -> tx_mutex_performance__priority_inheritance_count++;
#endif
}
#endif
}

#ifdef TX_MUTEX_INHERIT_CHAIN_MAX
TX_RESTORE
#endif

/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
#endif
Expand Down
Loading
Loading