import
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
#include <os_mutex.h>
|
||||
#include "os_critical.h"
|
||||
|
||||
|
||||
void os_mutex_init(os_mutex_t* self){
|
||||
self->owner = 0;
|
||||
os_waitobject_init(&self->wait_obj);
|
||||
}
|
||||
|
||||
void os_mutex_destroy(os_mutex_t* self){
|
||||
OS_ASSERT(self->owner==0);
|
||||
}
|
||||
|
||||
os_err_t os_mutex_trylock(os_mutex_t* self){
|
||||
os_critical_enter();
|
||||
os_task_t* p_thread = os_task_self();
|
||||
|
||||
if(self->owner!=0){ // 已经被锁定了
|
||||
if(self->owner==p_thread){ // 是当前任务锁定的
|
||||
os_critical_leave();
|
||||
return OS_ERR_OK;
|
||||
}
|
||||
|
||||
// 当前任务不是 owner,判断优先级是否反转
|
||||
if(os_priority_cmp(p_thread->curr_priority, self->owner->curr_priority)==OS_PRIORITY_CMP_HIGH){
|
||||
// 当前任务的优先级更高,优先级反转了,提升 owner 优先级
|
||||
self->owner->curr_priority = p_thread->curr_priority;
|
||||
}
|
||||
|
||||
os_critical_leave();
|
||||
return OS_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 到这里说明没有owner
|
||||
self->owner = (os_task_t*)p_thread;
|
||||
os_critical_leave();
|
||||
return OS_ERR_OK;
|
||||
}
|
||||
|
||||
os_err_t os_mutex_lock(os_mutex_t* self){
|
||||
|
||||
while(os_mutex_trylock(self)!=OS_ERR_OK){
|
||||
os_task_yield(); // 未获得锁,主动让出
|
||||
}
|
||||
|
||||
return OS_ERR_OK;
|
||||
}
|
||||
|
||||
os_err_t os_mutex_timed_lock(os_mutex_t* self, os_tick_t ticks){
|
||||
if(os_mutex_trylock(self)!=OS_ERR_OK){
|
||||
os_critical_enter();
|
||||
os_task_t* p_task = os_task_self();
|
||||
os_critical_leave();
|
||||
return os_waitobject_timed_wait(&self->wait_obj, p_task, ticks);
|
||||
}
|
||||
return OS_ERR_OK;
|
||||
}
|
||||
|
||||
void os_mutex_unlock(os_mutex_t* self){
|
||||
os_critical_enter();
|
||||
|
||||
os_task_t* p_task = os_task_self();
|
||||
|
||||
if(self->owner != p_task){
|
||||
// 只有 owner 才能 unlock
|
||||
os_critical_leave();
|
||||
os_task_yield();
|
||||
return;
|
||||
}
|
||||
|
||||
if(self->owner->curr_priority!=self->owner->init_priority) {
|
||||
self->owner->curr_priority = self->owner->init_priority; /* 恢复优先级 */
|
||||
}
|
||||
self->owner = 0;
|
||||
|
||||
os_critical_leave();
|
||||
|
||||
os_waitobject_notify_all(&self->wait_obj);
|
||||
}
|
||||
|
||||
void os_mutex_unlock_one(os_mutex_t* self){
|
||||
os_critical_enter();
|
||||
|
||||
os_task_t* p_task = os_task_self();
|
||||
|
||||
if(self->owner != p_task){
|
||||
// 只有 owner 才能 unlock
|
||||
os_critical_leave();
|
||||
os_task_yield();
|
||||
return;
|
||||
}
|
||||
|
||||
if(self->owner->curr_priority!=self->owner->init_priority) {
|
||||
self->owner->curr_priority = self->owner->init_priority; /* 恢复优先级 */
|
||||
}
|
||||
self->owner = 0;
|
||||
|
||||
// 将所有等待任务加入就绪表,等待当前任务用时完成后进行调度
|
||||
|
||||
os_critical_leave();
|
||||
|
||||
os_waitobject_notify_one(&self->wait_obj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user