remove rt_mutex_holder, avoid priority donation to an interrupt
This commit is contained in:
parent
5d9816bd4a
commit
b9957f0957
|
@ -50,13 +50,6 @@ struct rt_task;
|
||||||
#define RT_MUTEX_RECURSIVE(name) \
|
#define RT_MUTEX_RECURSIVE(name) \
|
||||||
struct rt_mutex name = RT_MUTEX_INIT_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
15
src/rt.c
15
src/rt.c
|
@ -357,23 +357,28 @@ static void mutex_donate(struct rt_mutex *mutex)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
struct rt_task *holder = rt_mutex_holder(mutex);
|
uintptr_t holder = rt_atomic_load(&mutex->holder, RT_ATOMIC_RELAXED);
|
||||||
if (holder == NULL)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rt_task *const task =
|
||||||
|
(struct rt_task *)(holder & RT_MUTEX_HOLDER_MASK);
|
||||||
|
|
||||||
if (!rt_list_is_empty(&mutex->wait_list))
|
if (!rt_list_is_empty(&mutex->wait_list))
|
||||||
{
|
{
|
||||||
// Re-sort the mutex in the holder's mutex list.
|
// Re-sort the mutex in the holder's mutex list.
|
||||||
rt_list_remove(&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
|
/* Update the holder's priority and get the next mutex to calculate
|
||||||
* donation on, if any. */
|
* donation on, if any. */
|
||||||
mutex = task_donate(holder);
|
mutex = task_donate(task);
|
||||||
} while (mutex != NULL);
|
} while (mutex != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,11 @@ void rt_rwlock_wrunlock(struct rt_rwlock *lock)
|
||||||
|
|
||||||
void rt_rwlock_unlock(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);
|
rt_rwlock_wrunlock(lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue