summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortmmdh <[email protected]>2020-10-25 11:54:06 +0800
committertmmdh <[email protected]>2020-10-25 11:54:06 +0800
commit55c0a9f27900d19556d52110be6397f3ee15a6c3 (patch)
tree2286d80cc7bceafec15649ea0be4e6db449a3a2e /src
parentbd91d5497e792da95fb2ab8a47e67dd610e9a71d (diff)
fix the conflicting file.
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--]src/ipc.c43
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 ++;