| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #include <stddef.h>
- #include <stdint.h>
- #include "task.h"
- #include "kernel.h"
- #include "scheduler.h"
- #include "zv_time.h"
- static bool __zv_scheduler_event_ready(
- zv_kernel_t *,
- zv_task_t *target
- ) {
- zv_event_t *event = &target->event;
- if (event->type == ZV_EVENT_OBJECT || event->type == ZV_EVENT_DATA) {
- return true;
- }
- if (event->type == ZV_EVENT_TIMER) {
- zv_time_t current_time = zv_platform_get_time();
- if (event->content.time <= current_time) {
- return true;
- }
- }
- return false;
- }
- static void __zv_scheduler_update_single_task(
- zv_kernel_t *self,
- zv_task_t *target
- ) {
- if (__zv_scheduler_event_ready(self, target)) {
- target->state = ZV_TASK_READY;
- }
- if (target->state == ZV_TASK_READY) {
- ++target->age;
- }
- }
- void __zv_scheduler_update_tasks(zv_kernel_t *self) {
- for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
- __zv_scheduler_update_single_task(self, self->tasks + count);
- }
- }
- static zv_task_t * __zv_scheduler_basic(zv_kernel_t *self) {
- for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
- zv_task_t *current = self->tasks + count;
- if (current->state == ZV_TASK_READY) {
- return current;
- }
- }
- return NULL;
- }
- static zv_task_t * __zv_scheduler_priority_strict(zv_kernel_t *self) {
- zv_task_t *found = NULL;
- for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
- zv_task_t *current = self->tasks + count;
-
- if (current->state != ZV_TASK_READY) {
- continue;
- }
- if (found == NULL) {
- found = current;
- continue;
- }
-
- if (found->priority < current->priority) {
- found = current;
- continue;
- }
- }
- return found;
- }
- static zv_task_t * __zv_scheduler_priority_aging(zv_kernel_t *self) {
- zv_task_t *found = NULL;
- zv_priority_t found_priority;
- for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
- zv_task_t *current = self->tasks + count;
-
- if (current->state != ZV_TASK_READY) {
- continue;
- }
- if (found == NULL) {
- found = current;
- found_priority = found->priority + found->age;
- continue;
- }
-
- if (found_priority < (current->priority + current->age)) {
- found = current;
- found_priority = found->priority + found->age;
- continue;
- }
- }
- return found;
- }
- zv_task_t * __zv_scheduler_find_task(zv_kernel_t *self) {
- switch (self->scheduler) {
- case ZV_SCHEDULER_BASIC:
- return __zv_scheduler_basic(self);
- case ZV_SCHEDULER_PRIORITY_STRICT:
- return __zv_scheduler_priority_strict(self);
- case ZV_SCHEDULER_PRIORITY_AGING:
- return __zv_scheduler_priority_aging(self);
- default:
- return NULL;
- }
- }
- void __zv_scheduler_run_task(zv_kernel_t *self, zv_task_t *target) {
- target->state = ZV_TASK_RUNNING;
- zv_event_t event_copy = target->event;
-
- target->event.type = ZV_EVENT_EMPTY;
- target->event.content.unumber = 0;
- zv_state_t result = target->worker(
- self,
- &event_copy,
- __zv_kernel_get_tid(self, target),
- target->param
- );
- if (result == ZV_TASK_READY || result == ZV_TASK_RUNNING) {
- result = ZV_TASK_READY;
- }
- target->state = result;
- target->age = 0x00;
- }
|