Files

135 lines
4.4 KiB
C
Raw Permalink Normal View History

2026-05-19 11:49:22 +08:00
#include <os_waitobject.h>
#include <os_critical.h>
#include "os_rdy_list.h"
#include "os_priority.h"
void os_waitobject_on_timeout(os_timer_t* timer){
os_task_t* p_thread = timer->userdata;
os_rdy_list_insert(p_thread);
p_thread->errors = OS_ERR_TIMEOUT;
// p_thread->state = OS_TASK_STATE_READY;
p_thread->remain_ticks = p_thread->init_ticks;
// 是否需要抢占当前任务
os_task_t* p_curr_thread_p = os_task_self();
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
// 不要改变时间窗
// 默认 timewheel 在有 timeout 的 timer 时,会要求调度,因此这里不需要调度
}
}
}
os_err_t os_waitobject_timed_wait(os_waitobject_t* self, os_task_t* task, os_tick_t ticks){
os_critical_enter();
if(ticks==0){
os_critical_leave();
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
os_timewheel_add_timer(&task->timer, os_waitobject_on_timeout
, task, ticks, OS_TIMER_FLAG_ONCE);
}else{
// WAIT_INFINITY
os_waitobject_wait_infinity(self, task);
}
os_critical_leave();
os_sched();
if(task->errors!=OS_ERR_OK){
os_err_t err = task->errors;
task->errors = OS_ERR_OK;
return err;
}
return OS_ERR_OK;
}
os_err_t os_waitobject_wait_until(os_waitobject_t* self, os_task_t* task, os_tick_t ticks){
os_critical_enter();
if(ticks==0){
os_critical_leave();
return OS_ERR_TIMEOUT;
}else if(ticks!=OS_WAIT_INFINITY){
os_timewheel_add_until_timer(&task->timer, os_waitobject_on_timeout
, task, ticks, OS_TIMER_FLAG_ONCE);
}else{
// WAIT_INFINITY
os_waitobject_wait_infinity(self, task);
}
os_critical_leave();
os_sched();
if(task->errors!=OS_ERR_OK){
os_err_t err = task->errors;
task->errors = OS_ERR_OK;
return err;
}
return OS_ERR_OK;
}
void os_waitobject_notify_one_in_isr(os_waitobject_t* self){
os_critical_enter_in_isr();
if(os_list_is_empty(&self->wait_list)){
os_critical_leave_in_isr();
return;
}
os_list_node_t* p = self->wait_list.next;
os_list_remove(p);
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
os_rdy_list_insert(p_thread);
// p_thread->state = OS_TASK_STATE_READY;
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
os_task_t* p_curr_thread_p = os_task_self();
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
// 不要改变时间窗
}
}
os_critical_leave_in_isr();
os_sched_in_isr();
}
void os_waitobject_notify_all_in_isr(os_waitobject_t * self){
os_critical_enter_in_isr();
os_list_node_t* p = self->wait_list.next;
os_task_t* p_curr_thread_p = os_task_self();
for(;p!=&self->wait_list;){
os_task_t* p_thread = os_list_member_of(p, os_task_t, node);
p = p->next;
os_list_remove(&p_thread->node);
// 将任务加入就绪表
os_rdy_list_insert(p_thread);
p_thread->remain_ticks = p_thread->init_ticks;
// 尝试抢占当前任务
if(p_curr_thread_p && p_curr_thread_p->state==kOsTaskState_Running){
if(os_priority_is_high(p_thread->curr_priority, p_curr_thread_p->curr_priority)){
os_priority_set(p_curr_thread_p->curr_priority);
os_rdy_list_insert_head(p_curr_thread_p); // 放到头部,这样下次调度可以尽快调度这个任务
p_curr_thread_p->state = kOsTaskState_Ready; // 就绪状态
}
}
}
os_critical_leave_in_isr();
os_sched_in_isr();
}