process.hpp 2.9 KB

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