remove rt_mutex_holder, avoid priority donation to an interrupt

This commit is contained in:
Chris Copeland 2024-03-31 22:42:54 -07:00
parent 5d9816bd4a
commit b9957f0957
Signed by: chrisnc
GPG Key ID: 14550DA72485DF30
3 changed files with 15 additions and 13 deletions

View File

@ -50,13 +50,6 @@ struct rt_task;
#define RT_MUTEX_RECURSIVE(name) \
struct rt_mutex name = RT_MUTEX_INIT_RECURSIVE(name)
static inline struct rt_task *rt_mutex_holder(const struct rt_mutex *mutex)
{
return (struct rt_task *)(rt_atomic_load(&mutex->holder,
RT_ATOMIC_RELAXED) &
RT_MUTEX_HOLDER_MASK);
}
#ifdef __cplusplus
}
#endif

View File

@ -357,23 +357,28 @@ static void mutex_donate(struct rt_mutex *mutex)
{
do
{
struct rt_task *holder = rt_mutex_holder(mutex);
if (holder == NULL)
uintptr_t holder = rt_atomic_load(&mutex->holder, RT_ATOMIC_RELAXED);
if ((holder == RT_MUTEX_UNLOCKED) ||
(holder == RT_MUTEX_HOLDER_INTERRUPT))
{
// If the mutex is not held then no donation is needed.
/* If the mutex is not held or held by an interrupt, then no
* donation is needed. */
return;
}
struct rt_task *const task =
(struct rt_task *)(holder & RT_MUTEX_HOLDER_MASK);
if (!rt_list_is_empty(&mutex->wait_list))
{
// Re-sort the mutex in the holder's mutex list.
rt_list_remove(&mutex->list);
insert_mutex_by_priority(&holder->mutex_list, mutex);
insert_mutex_by_priority(&task->mutex_list, mutex);
}
/* Update the holder's priority and get the next mutex to calculate
* donation on, if any. */
mutex = task_donate(holder);
mutex = task_donate(task);
} while (mutex != NULL);
}

View File

@ -215,7 +215,11 @@ void rt_rwlock_wrunlock(struct rt_rwlock *lock)
void rt_rwlock_unlock(struct rt_rwlock *lock)
{
if (rt_mutex_holder(&lock->mutex) == rt_task_self())
const uintptr_t holder =
rt_atomic_load(&lock->mutex.holder, RT_ATOMIC_RELAXED) &
RT_MUTEX_HOLDER_MASK;
if ((holder == (uintptr_t)rt_task_self()) ||
(holder == RT_MUTEX_HOLDER_INTERRUPT))
{
rt_rwlock_wrunlock(lock);
}