#include #include #include #include #include static void __zv_scheduler_update_task(zv_task_t *target) { if (__zv_event_is_working_timer(target->event)) { __zv_time_process_timer(&target->event); } if (__zv_event_is_set(target->event)) { target->state = ZV_TASK_READY; } if (target->state == ZV_TASK_READY) { ++target->age; } } static void __zv_scheduler_run_task(zv_kernel_t *self, zv_tid_t target_tid) { zv_task_t *target = __zv_kernel_get_task(self, target_tid); zv_event_t event_copy = target->event; __zv_task_mark_running(target); __zv_task_clear_age(target); __zv_event_clear(&target->event); zv_state_t exit_state = target->worker( self, &event_copy, target_tid, target->param ); if (exit_state == ZV_TASK_RUNNING) { exit_state = ZV_TASK_READY; } if (exit_state == ZV_TASK_EMPTY || exit_state == ZV_TASK_KILLED) { zv_kernel_kill_process(self, target_tid); return; } target->state = exit_state; } static zv_tid_t __zv_scheduler_select_next_task(zv_kernel_t *self) { zv_tid_t selected = ZV_TID_NULL; zv_priority_t selected_priority = 0; for (zv_tid_t count = 0; count < self->tasks_count; ++count) { zv_task_t *current = __zv_kernel_get_task(self, count); __zv_scheduler_update_task(current); if (!__zv_task_is_ready(current)) { continue; } zv_priority_t current_priority = __zv_task_calc_priority(current); if (selected == ZV_TID_NULL || current_priority > selected_priority) { selected = count; selected_priority = current_priority; } } return selected; } bool __zv_scheduler_single_loop(zv_kernel_t *self) { zv_tid_t next_task = __zv_scheduler_select_next_task(self); if (next_task == ZV_TID_NULL) { if (!self->idle_worker(self)) { return false; } return true; } __zv_scheduler_run_task(self, next_task); return true; }