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
211 changes: 211 additions & 0 deletions common/src/tx_mutex_cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
/* */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* _tx_mutex_inherit_priority_update Update priority inheritance */
/* */
/* CALLED BY */
/* */
Expand Down Expand Up @@ -155,6 +156,37 @@ TX_THREAD *previous_thread;
}
}

/* Determine if priority inheritance is in effect. */
if (mutex_ptr -> tx_mutex_inherit == TX_TRUE)
{

/* The departing thread may be the one whose priority the owner
inherited, and it has not obtained the mutex, so nothing else
will undo that inheritance until the owner releases the mutex.
Recompute the owner's priority from the remaining waiters. */

#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_mutex_inherit_priority_update(mutex_ptr);

#ifndef TX_NOT_INTERRUPTABLE

/* Disable interrupts. */
TX_DISABLE

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

/* 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 Expand Up @@ -307,3 +339,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);
}
}
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
Loading
Loading