diff options
| author | tmmdh <[email protected]> | 2020-10-25 11:54:06 +0800 |
|---|---|---|
| committer | tmmdh <[email protected]> | 2020-10-25 11:54:06 +0800 |
| commit | 55c0a9f27900d19556d52110be6397f3ee15a6c3 (patch) | |
| tree | 2286d80cc7bceafec15649ea0be4e6db449a3a2e /src | |
| parent | bd91d5497e792da95fb2ab8a47e67dd610e9a71d (diff) | |
fix the conflicting file.
Diffstat (limited to 'src')
| -rwxr-xr-x[-rw-r--r--] | src/ipc.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/ipc.c b/src/ipc.c index 454fcb5439..4c1d4a756a 100644..100755 --- a/src/ipc.c +++ b/src/ipc.c @@ -37,6 +37,7 @@ * 2020-07-29 Meco Man fix thread->event_set/event_info when received an * event without pending * 2020-10-11 Meco Man add value overflow-check code + * 2020-10-25 hupu fix priority inversion bug of mutex */ #include <rtthread.h> @@ -190,6 +191,31 @@ rt_inline rt_err_t rt_ipc_list_resume_all(rt_list_t *list) return RT_EOK; } +/** + * This function will get the highest priority from the specified + * list of threads + * + * @param list of the threads + * + * @return the highest priority + */ +rt_uint8_t rt_ipc_get_highest_priority(rt_list_t *list) +{ + struct rt_list_node *n; + struct rt_thread *sthread; + rt_uint8_t priority = RT_THREAD_PRIORITY_MAX - 1; + + for (n = list->next; n != list; n = n->next) + { + sthread = rt_list_entry(n, struct rt_thread, tlist); + + priority = priority < sthread->current_priority ? + priority : + sthread->current_priority; + } + return priority; +} + #ifdef RT_USING_SEMAPHORE /** * This function will initialize a semaphore and put it under control of @@ -828,6 +854,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) register rt_base_t temp; struct rt_thread *thread; rt_bool_t need_schedule; + rt_uint8_t max_priority_in_queue = RT_THREAD_PRIORITY_MAX - 1; /* parameter check */ RT_ASSERT(mutex != RT_NULL); @@ -888,6 +915,22 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) /* set new owner and priority */ mutex->owner = thread; mutex->original_priority = thread->current_priority; + + /* Priority adjustment occurs only when the following conditions + * are met simultaneously: + * 1.The type of mutex is RT_IPC_FLAG_FIFO; + * 2.The priority of the thread to be resumed is not equal to the + * highest priority in the queue; + */ + max_priority_in_queue = rt_ipc_get_highest_priority(&mutex->parent.suspend_thread); + if (mutex->parent.parent.flag == RT_IPC_FLAG_FIFO && + thread->current_priority != max_priority_in_queue) + { + rt_thread_control(thread, + RT_THREAD_CTRL_CHANGE_PRIORITY, + &(max_priority_in_queue)); + } + if(mutex->hold < RT_MUTEX_HOLD_MAX) { mutex->hold ++; |
