scheduler.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "kernel.h"
  2. #include "scheduler.h"
  3. static inline void zv_kernel_exec_process(
  4. zv_kernel_t *self,
  5. zv_process_t *target
  6. ) {
  7. bool was_interrupted = (target->state == ZV_INTERRUPTED);
  8. if (was_interrupted && self->interrupts > 0) {
  9. --self->interrupts;
  10. }
  11. target->state = ZV_WORKING;
  12. zv_state_t result = target->worker(self, target);
  13. if (result == ZV_WORKING || result == ZV_INTERRUPTED) {
  14. result = ZV_READY;
  15. }
  16. if (was_interrupted) {
  17. result = ZV_INTERRUPT_WAITING;
  18. }
  19. target->state = result;
  20. }
  21. static inline zv_process_t * zv_kernel_select_process(zv_kernel_t *self) {
  22. if (self->interrupts > 0) {
  23. zv_process_t *selected = zv_kernel_scheduler_select_interrupted(self);
  24. if (selected != NULL) {
  25. return selected;
  26. }
  27. self->interrupts = 0;
  28. }
  29. return zv_kernel_scheduler_mode_selector(self);
  30. }
  31. void zv_kernel_scheduler_single_loop(zv_kernel_t *self) {
  32. zv_process_t *selected = zv_kernel_select_process(self);
  33. if (selected == NULL) {
  34. zv_kernel_idle_task();
  35. return;
  36. }
  37. zv_kernel_exec_process(self, selected);
  38. self->last = zv_kernel_get_pid(self, selected);
  39. }
  40. void zv_kernel_scheduler(zv_kernel_t *self) {
  41. while (true) {
  42. zv_kernel_scheduler_single_loop(self);
  43. }
  44. }