process.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #pragma once
  2. #include <kernel/event/evtqueue.hpp>
  3. #include <kernel/interrupt.h>
  4. #include <kernel/mm.hpp>
  5. #include <kernel/task.h>
  6. #include <types/hash_map.hpp>
  7. #include <types/list.hpp>
  8. #include <types/stdint.h>
  9. #include <types/types.h>
  10. typedef size_t pid_t;
  11. class process;
  12. struct thread;
  13. struct process_attr {
  14. uint16_t system : 1;
  15. uint16_t zombie : 1 = 0;
  16. };
  17. struct thread_attr {
  18. uint32_t system : 1;
  19. uint32_t ready : 1;
  20. uint32_t wait : 1;
  21. };
  22. struct thread {
  23. private:
  24. inline void alloc_kstack(void)
  25. {
  26. // TODO: alloc low mem
  27. kstack = to_pp(alloc_n_raw_pages(2));
  28. kstack += THREAD_KERNEL_STACK_SIZE;
  29. esp = reinterpret_cast<uint32_t*>(kstack);
  30. }
  31. public:
  32. uint32_t* esp;
  33. pptr_t kstack;
  34. process* owner;
  35. thread_attr attr;
  36. explicit inline thread(process* _owner, bool system)
  37. : owner { _owner }
  38. , attr {
  39. .system = system,
  40. .ready = 1,
  41. .wait = 0,
  42. }
  43. {
  44. alloc_kstack();
  45. }
  46. constexpr thread(thread&& val)
  47. : esp { val.esp }
  48. , kstack { val.kstack }
  49. , owner { val.owner }
  50. , attr { val.attr }
  51. {
  52. val.attr = {};
  53. val.esp = 0;
  54. val.kstack = 0;
  55. val.owner = nullptr;
  56. }
  57. inline thread(const thread& val)
  58. : owner { val.owner }
  59. , attr { val.attr }
  60. {
  61. alloc_kstack();
  62. }
  63. constexpr ~thread()
  64. {
  65. if (kstack)
  66. free_n_raw_pages(to_page(kstack), 2);
  67. }
  68. };
  69. class process {
  70. public:
  71. mutable kernel::mm_list mms;
  72. types::list<thread> thds;
  73. kernel::evtqueue wait_lst;
  74. process_attr attr;
  75. pid_t pid;
  76. pid_t ppid;
  77. public:
  78. process(process&& val);
  79. process(const process&) = delete;
  80. process(const process& proc, const thread& main_thread);
  81. // only used for system initialization
  82. explicit process(void);
  83. explicit process(void (*func_in_kernel_space)(void), pid_t ppid);
  84. ~process();
  85. private:
  86. static inline pid_t max_pid;
  87. static inline pid_t alloc_pid(void)
  88. {
  89. return ++max_pid;
  90. }
  91. };
  92. constexpr uint32_t push_stack(uint32_t** stack, uint32_t val)
  93. {
  94. --*stack;
  95. **stack = val;
  96. return val;
  97. }
  98. inline process* volatile current_process;
  99. inline thread* volatile current_thread;
  100. inline typename types::hash_map<pid_t, types::list<pid_t>, types::linux_hasher<pid_t>>* idx_child_processes;
  101. extern "C" void NORETURN init_scheduler();
  102. void schedule(void);
  103. pid_t add_to_process_list(process&& proc);
  104. void remove_from_process_list(pid_t pid);
  105. void add_to_ready_list(thread* thd);
  106. void remove_from_ready_list(thread* thd);
  107. types::list<thread*>::iterator_type query_next_thread(void);
  108. // the function call INVALIDATES iterator
  109. inline void next_task(types::list<thread*>::iterator_type target)
  110. {
  111. auto* ptr = *target;
  112. remove_from_ready_list(ptr);
  113. if (ptr->attr.ready)
  114. add_to_ready_list(ptr);
  115. }
  116. process* findproc(pid_t pid);
  117. void k_new_thread(void (*func)(void*), void* data);