import
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
#include <os_condv.h>
|
||||
#include "os_critical.h"
|
||||
#include "os_rdy_list.h"
|
||||
#include "os_sched.h"
|
||||
#include "os_timewheel.h"
|
||||
|
||||
void os_condv_init(os_condv_t* self){
|
||||
os_list_init(&self->wait_list);
|
||||
}
|
||||
|
||||
void os_condv_destroy(os_condv_t* self){
|
||||
OS_ASSERT(os_list_is_empty(&self->wait_list));
|
||||
}
|
||||
|
||||
void os_condv_wait(os_condv_t* self, os_mutex_t* lock){
|
||||
os_mutex_unlock(lock);
|
||||
os_critical_enter();
|
||||
os_task_t* p_thread = os_task_self();
|
||||
os_list_insert_before(&self->wait_list, &p_thread->node);
|
||||
p_thread->state = kOsTaskState_Wait;
|
||||
os_critical_leave();
|
||||
os_sched();
|
||||
os_mutex_lock(lock);
|
||||
}
|
||||
|
||||
|
||||
void os_condv_notify_one(os_condv_t* self){
|
||||
os_critical_enter();
|
||||
if(os_list_is_empty(&self->wait_list)){
|
||||
os_critical_leave();
|
||||
return;
|
||||
}
|
||||
|
||||
os_list_node_t* p = self->wait_list.next;
|
||||
os_task_t* thread = os_list_member_of(p, os_task_t, node);
|
||||
os_list_remove(&thread->node);
|
||||
os_rdy_list_insert(thread);
|
||||
os_critical_leave();
|
||||
|
||||
os_sched();
|
||||
}
|
||||
|
||||
void os_condv_notify_all(os_condv_t* self){
|
||||
os_critical_enter();
|
||||
for(os_list_node_t* p = self->wait_list.next; p!=&self->wait_list; ){
|
||||
os_task_t* thread = os_list_member_of(p, os_task_t, node);
|
||||
p = p->next;
|
||||
os_list_remove(&thread->node);
|
||||
os_rdy_list_insert(thread);
|
||||
}
|
||||
os_critical_leave();
|
||||
|
||||
os_sched();
|
||||
}
|
||||
|
||||
|
||||
static void os_condv_ontimeout(os_timer_t* p_timer){
|
||||
os_task_t* p_thread = os_list_member_of(p_timer, os_task_t, timer);
|
||||
os_list_remove(&p_thread->node); // 从 WAIT 列表中移除
|
||||
p_thread->errors = OS_ERR_TIMEOUT; // 标记超时了
|
||||
os_rdy_list_insert(p_thread); // 加入就绪表
|
||||
}
|
||||
|
||||
os_err_t os_condv_timed_wait(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks){
|
||||
os_err_t err = OS_ERR_OK;
|
||||
os_mutex_unlock(lock);
|
||||
{
|
||||
os_critical_enter();
|
||||
os_task_t* p_thread = os_task_self();
|
||||
os_list_insert_before(&self->wait_list, &p_thread->node);
|
||||
p_thread->state = kOsTaskState_Wait;
|
||||
|
||||
if(ticks==0){
|
||||
// TIMEOUT
|
||||
p_thread->errors = OS_ERR_TIMEOUT;
|
||||
os_critical_leave();
|
||||
os_mutex_lock(lock);
|
||||
return OS_ERR_TIMEOUT;
|
||||
}else if(ticks!=OS_WAIT_INFINITY){
|
||||
// 定时
|
||||
p_thread->errors = OS_ERR_OK;
|
||||
os_timewheel_add_timer((os_timer_t*)&p_thread->timer, os_condv_ontimeout, 0, ticks, OS_TIMER_FLAG_ONCE);
|
||||
}
|
||||
os_critical_leave();
|
||||
}
|
||||
|
||||
os_sched();
|
||||
|
||||
{
|
||||
// 返回当前线程
|
||||
os_critical_enter();
|
||||
os_task_t* p_task = os_task_self();
|
||||
err = p_task->errors;
|
||||
if(err!=OS_ERR_OK){
|
||||
p_task->errors = OS_ERR_OK;
|
||||
os_critical_leave();
|
||||
os_mutex_lock(lock);
|
||||
return err;
|
||||
}
|
||||
os_critical_leave();
|
||||
}
|
||||
|
||||
os_mutex_lock(lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
os_err_t os_condv_wait_until(os_condv_t* self, os_mutex_t* lock, os_tick_t ticks){
|
||||
os_err_t err = OS_ERR_OK;
|
||||
os_mutex_unlock(lock);
|
||||
{
|
||||
os_critical_enter();
|
||||
os_task_t* p_thread = os_task_self();
|
||||
os_list_insert_before(&self->wait_list, &p_thread->node);
|
||||
p_thread->state = kOsTaskState_Wait;
|
||||
|
||||
if(ticks==0){
|
||||
// TIMEOUT
|
||||
p_thread->errors = OS_ERR_TIMEOUT;
|
||||
os_critical_leave();
|
||||
os_mutex_lock(lock);
|
||||
return OS_ERR_TIMEOUT;
|
||||
}else if(ticks!=OS_WAIT_INFINITY){
|
||||
// 定时
|
||||
p_thread->errors = OS_ERR_OK;
|
||||
os_timewheel_add_until_timer((os_timer_t*)&p_thread->timer
|
||||
, os_condv_ontimeout, 0
|
||||
, ticks, OS_TIMER_FLAG_ONCE);
|
||||
}
|
||||
os_critical_leave();
|
||||
}
|
||||
|
||||
os_sched();
|
||||
{
|
||||
os_critical_enter();
|
||||
os_task_t* p_task = os_task_self();
|
||||
err = p_task->errors;
|
||||
if(err!=OS_ERR_OK){
|
||||
p_task->errors = OS_ERR_OK;
|
||||
os_critical_leave();
|
||||
os_mutex_lock(lock);
|
||||
return err;
|
||||
}
|
||||
os_critical_leave();
|
||||
}
|
||||
|
||||
os_mutex_lock(lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
void os_condv_notify_one_in_isr(os_condv_t* self){
|
||||
os_critical_enter_in_isr();
|
||||
if(os_list_is_empty(&self->wait_list)){
|
||||
os_critical_leave();
|
||||
return;
|
||||
}
|
||||
|
||||
os_list_node_t* p = self->wait_list.next;
|
||||
os_task_t* thread = os_list_member_of(p, os_task_t, node);
|
||||
os_list_remove(&thread->node);
|
||||
os_rdy_list_insert(thread);
|
||||
// thread->state = OS_TASK_STATE_READY;
|
||||
os_critical_leave_in_isr();
|
||||
|
||||
os_sched_in_isr();
|
||||
}
|
||||
|
||||
void os_condv_notify_all_in_isr(os_condv_t* self){
|
||||
os_critical_enter_in_isr();
|
||||
for(os_list_node_t* p = self->wait_list.next; p!=&self->wait_list; ){
|
||||
os_task_t* thread = os_list_member_of(p, os_task_t, node);
|
||||
os_list_remove(&thread->node);
|
||||
p = p->next;
|
||||
os_rdy_list_insert(thread);
|
||||
// thread->state = OS_TASK_STATE_READY;
|
||||
}
|
||||
os_critical_leave_in_isr();
|
||||
|
||||
os_sched_in_isr();
|
||||
}
|
||||
Reference in New Issue
Block a user