#include #include #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(); }