kernel.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <zivuos.h>
  2. #include <stddef.h>
  3. static inline void __zv_kernel_init_task(zv_task_t *target) {
  4. target->state = ZV_TASK_EMPTY;
  5. target->param = NULL;
  6. target->event.type = ZV_EVENT_EMPTY;
  7. target->event.content.unumber = 0;
  8. target->age = 0;
  9. target->priority = 0;
  10. target->worker = NULL;
  11. }
  12. /**
  13. * @brief That initialize kernel structure.
  14. * @param self Pointer to kernel structure to work on.
  15. * @param tasks Pointer to tasks stack.
  16. * @param count Number of tasks slots on stack.
  17. * @return True when kernel initialized success or false when not.
  18. */
  19. bool zv_kernel_init(zv_kernel_t *self, zv_task_t *tasks, zv_tid_t count) {
  20. if (self == NULL || tasks == NULL || count < 2) {
  21. return false;
  22. }
  23. self->tasks = tasks;
  24. self->tasks_count = count;
  25. self->idle_worker = zv_idle_worker_default;
  26. for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
  27. __zv_kernel_init_task(self->tasks + count);
  28. }
  29. return true;
  30. }
  31. /**
  32. * @brief That boot OS. It return when task stack is empty.
  33. * @return True when everything is executed, and all tasks had been killed.
  34. * False when something went wrong.
  35. */
  36. bool zv_kernel_boot(zv_kernel_t *self) {
  37. while (true) {
  38. bool any_task_exists = __zv_scheduler_single_loop(self);
  39. if (!any_task_exists) {
  40. return true;
  41. }
  42. }
  43. return false;
  44. }
  45. zv_tid_t zv_kernel_create_process(
  46. zv_kernel_t *self,
  47. zv_worker_t worker,
  48. zv_priority_t priority,
  49. void *param
  50. ) {
  51. zv_tid_t slot = __zv_kernel_get_empty_slot(self);
  52. if (slot == ZV_TID_NULL) {
  53. return ZV_TID_NULL;
  54. }
  55. zv_task_t *target = self->tasks + slot;
  56. target->param = param;
  57. target->worker = worker;
  58. target->age = 0;
  59. target->priority = priority;
  60. target->state = ZV_TASK_READY;
  61. return slot;
  62. }
  63. bool zv_kernel_kill_process(
  64. zv_kernel_t *self,
  65. zv_tid_t target
  66. ) {
  67. zv_task_t *current = self->tasks + target;
  68. if (current->state == ZV_TASK_EMPTY) {
  69. return false;
  70. }
  71. current->state = ZV_TASK_EMPTY;
  72. return true;
  73. }
  74. zv_tid_t __zv_kernel_get_empty_slot(zv_kernel_t *self) {
  75. for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
  76. zv_task_t *current = self->tasks + count;
  77. if (current->state == ZV_TASK_EMPTY) {
  78. return count;
  79. }
  80. }
  81. return ZV_TID_NULL;
  82. }
  83. zv_task_t * __zv_kernel_get_task(zv_kernel_t *self, zv_tid_t target) {
  84. return self->tasks + target;
  85. }
  86. zv_tid_t __zv_kernel_get_tid(zv_kernel_t *self, zv_task_t *target) {
  87. return target - self->tasks;
  88. }