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
1 change: 1 addition & 0 deletions common/inc/tx_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ VOID _tx_mutex_initialize(VOID);
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);
VOID _tx_mutex_inherit_priority_update(TX_MUTEX *mutex_ptr);


/* Mutex management component data declarations follow. */
Expand Down
7 changes: 7 additions & 0 deletions common/inc/tx_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ THREAD_DECLARE volatile UINT _tx_thread_preempt_disable;
THREAD_DECLARE VOID (*_tx_thread_mutex_release)(TX_THREAD *thread_ptr);


/* Define the global function pointer that updates the priority inheritance of a mutex
after the priority of a thread waiting on it changes. This pointer is setup during
mutex initialization. */

THREAD_DECLARE VOID (*_tx_thread_mutex_priority_update)(TX_MUTEX *mutex_ptr);


/* Define the global build options variable. This contains a bit map representing
how the ThreadX library was built. The following are the bit field definitions:

Expand Down
179 changes: 179 additions & 0 deletions common/src/tx_mutex_cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,182 @@ UINT status;
TX_RESTORE
}



/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_mutex_inherit_priority_update PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function brings the priority inheritance of a mutex and of */
/* its owner up to date after the set of threads waiting on the mutex, */
/* or the priority of one of them, has changed other than through */
/* tx_mutex_get or tx_mutex_put. The highest priority waiting on the */
/* mutex is recomputed from its suspension list, the owner's inherited */
/* priority is recomputed from every priority inheritance mutex it */
/* owns, and the owner's priority is changed if it differs from the */
/* higher of that and its own user priority. */
/* */
/* Unless TX_NOT_INTERRUPTABLE is defined, the caller must have */
/* preemption disabled and interrupts enabled, as for */
/* _tx_mutex_priority_change. Otherwise interrupts must be disabled. */
/* */
/* INPUT */
/* */
/* mutex_ptr Pointer to mutex control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_mutex_prioritize Move highest priority waiter to */
/* the front of the list */
/* _tx_mutex_priority_change Change owner's priority */
/* */
/* CALLED BY */
/* */
/* ThreadX internal code */
/* */
/**************************************************************************/
VOID _tx_mutex_inherit_priority_update(TX_MUTEX *mutex_ptr)
{

#ifndef TX_NOT_INTERRUPTABLE
TX_INTERRUPT_SAVE_AREA
#endif

TX_THREAD *owner_ptr;
TX_THREAD *suspended_thread;
TX_MUTEX *next_mutex;
UINT inheritance_priority;
UINT new_priority;
#ifdef TX_MISRA_ENABLE
UINT status;
#endif


/* Determine if there is more than one thread suspended on the mutex. */
if (mutex_ptr -> tx_mutex_suspended_count > ((UINT) 1))
{

/* Yes, prioritize the list so the highest priority thread is placed at the
front of the suspension list. */
#ifdef TX_MISRA_ENABLE
do
{
status = _tx_mutex_prioritize(mutex_ptr);
} while (status != TX_SUCCESS);
#else
_tx_mutex_prioritize(mutex_ptr);
#endif
}

#ifndef TX_NOT_INTERRUPTABLE

/* Disable interrupts. */
TX_DISABLE
#endif

/* Pickup the thread at the front of the suspension list. */
suspended_thread = mutex_ptr -> tx_mutex_suspension_list;

/* Determine if there still are threads suspended for this mutex. */
if (suspended_thread != TX_NULL)
{

/* Setup the highest priority thread waiting on this mutex. */
mutex_ptr -> tx_mutex_highest_priority_waiting = suspended_thread -> tx_thread_priority;
}
else
{

/* No thread is waiting on this mutex. */
mutex_ptr -> tx_mutex_highest_priority_waiting = ((UINT) TX_MAX_PRIORITIES);
}

/* Pickup the mutex owner. */
owner_ptr = mutex_ptr -> tx_mutex_owner;

#ifndef TX_NOT_INTERRUPTABLE

/* Restore interrupts. */
TX_RESTORE
#endif

/* The owner is not NULL. A thread could only suspend on this mutex while a
thread owned it, since tx_mutex_get raises the owner's priority when it does,
and the owner keeps the mutex for as long as this processing can run. */

/* Default the inheritance priority to disabled. */
inheritance_priority = ((UINT) TX_MAX_PRIORITIES);

/* Search the mutexes owned by this thread to determine the highest priority
it still inherits. */
next_mutex = owner_ptr -> tx_thread_owned_mutex_list;
while (next_mutex != TX_NULL)
{

/* Does this mutex support priority inheritance? */
if (next_mutex -> tx_mutex_inherit == TX_TRUE)
{

/* Determine if highest priority field of the mutex is higher than the
inheritance priority so far. */
if (next_mutex -> tx_mutex_highest_priority_waiting < inheritance_priority)
{

/* Use this priority. */
inheritance_priority = next_mutex -> tx_mutex_highest_priority_waiting;
}
}

/* Move mutex pointer to the next mutex in the list. */
next_mutex = next_mutex -> tx_mutex_owned_next;

/* Are we at the end of the list? */
if (next_mutex == owner_ptr -> tx_thread_owned_mutex_list)
{

/* Yes, set the next mutex to NULL. */
next_mutex = TX_NULL;
}
}

#ifndef TX_NOT_INTERRUPTABLE

/* Disable interrupts. */
TX_DISABLE
#endif

/* Set the inherit priority to that of the highest priority thread waiting on
any mutex the owner holds. */
owner_ptr -> tx_thread_inherit_priority = inheritance_priority;

/* The owner runs at the higher of its own priority and the inherited one. */
new_priority = owner_ptr -> tx_thread_user_priority;
if (inheritance_priority < new_priority)
{

/* Use the inherited priority. */
new_priority = inheritance_priority;
}

#ifndef TX_NOT_INTERRUPTABLE

/* Restore interrupts. */
TX_RESTORE
#endif

/* Determine if the owner's priority has to change. */
if (owner_ptr -> tx_thread_priority != new_priority)
{

/* Yes, change the priority of the owner. */
_tx_mutex_priority_change(owner_ptr, new_priority);
}
}
4 changes: 3 additions & 1 deletion common/src/tx_mutex_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

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


/**************************************************************************/
/**************************************************************************/
/** */
Expand Down Expand Up @@ -92,6 +91,9 @@ TX_MUTEX *previous_mutex;
/* Setup the thread mutex release function pointer. */
_tx_thread_mutex_release = &(_tx_mutex_thread_release);

/* Setup the thread mutex priority update function pointer. */
_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. */
if (_tx_mutex_created_count == TX_EMPTY)
Expand Down
10 changes: 10 additions & 0 deletions common/src/tx_thread_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ volatile UINT _tx_thread_preempt_disable;
VOID (*_tx_thread_mutex_release)(TX_THREAD *thread_ptr);


/* Define the global function pointer that updates the priority inheritance of a mutex
after the priority of a thread waiting on it changes. This pointer is setup during
mutex initialization. */

VOID (*_tx_thread_mutex_priority_update)(TX_MUTEX *mutex_ptr);


/* Define the global build options variable. This contains a bit map representing
how the ThreadX library was built. The following are the bit field definitions:

Expand Down Expand Up @@ -348,6 +355,9 @@ VOID _tx_thread_initialize(VOID)
/* Initialize the thread mutex release function pointer. */
_tx_thread_mutex_release = TX_NULL;

/* Initialize the thread mutex priority update function pointer. */
_tx_thread_mutex_priority_update = TX_NULL;

#ifdef TX_ENABLE_STACK_CHECKING

/* Clear application registered stack error handler. */
Expand Down
46 changes: 44 additions & 2 deletions common/src/tx_thread_priority_change.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* _tx_thread_system_suspend Suspend thread */
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
/* _tx_thread_mutex_priority_update Update mutex inheritance */
/* _tx_thread_system_preempt_check Check for preemption */
/* */
/* CALLED BY */
Expand All @@ -79,6 +80,7 @@ UINT _tx_thread_priority_change(TX_THREAD *thread_ptr, UINT new_priority, UINT
TX_INTERRUPT_SAVE_AREA

TX_THREAD *execute_ptr;
TX_MUTEX *mutex_ptr;
TX_THREAD *next_execute_ptr;
UINT original_priority;

Expand Down Expand Up @@ -121,8 +123,48 @@ UINT original_priority;
thread_ptr -> tx_thread_preempt_threshold = thread_ptr -> tx_thread_inherit_priority;
}

/* Restore interrupts. */
TX_RESTORE
/* Determine if the thread is waiting on a mutex. */
if ((thread_ptr -> tx_thread_state == TX_MUTEX_SUSP) && (thread_ptr -> tx_thread_suspend_cleanup != TX_NULL))
{

/* Yes, the mutex owner may have inherited the old priority of this thread, or
may now have to inherit the new one. The update function pointer is set,
since a mutex has been created. */
mutex_ptr = TX_VOID_TO_MUTEX_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);

#ifndef TX_NOT_INTERRUPTABLE

/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;

/* Restore interrupts. */
TX_RESTORE
#endif

/* Update the priority inheritance of the mutex owner. */
(_tx_thread_mutex_priority_update)(mutex_ptr);

#ifndef TX_NOT_INTERRUPTABLE

/* Disable interrupts. */
TX_DISABLE

/* Back off the preemption disable. */
_tx_thread_preempt_disable--;
#endif

/* Restore interrupts. */
TX_RESTORE

/* Check for preemption. */
_tx_thread_system_preempt_check();
}
else
{

/* Restore interrupts. */
TX_RESTORE
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions common_smp/inc/tx_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ VOID _tx_mutex_initialize(VOID);
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);
VOID _tx_mutex_inherit_priority_update(TX_MUTEX *mutex_ptr);


/* Mutex management component data declarations follow. */
Expand Down
7 changes: 7 additions & 0 deletions common_smp/inc/tx_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ THREAD_DECLARE volatile UINT _tx_thread_preempt_disable;
THREAD_DECLARE VOID (*_tx_thread_mutex_release)(TX_THREAD *thread_ptr);


/* Define the global function pointer that updates the priority inheritance of a mutex
after the priority of a thread waiting on it changes. This pointer is setup during
mutex initialization. */

THREAD_DECLARE VOID (*_tx_thread_mutex_priority_update)(TX_MUTEX *mutex_ptr);


/* Define the global build options variable. This contains a bit map representing
how the ThreadX library was built. The following are the bit field definitions:

Expand Down
Loading
Loading