Thread.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #pragma once
  2. #include <AK/AKString.h>
  3. #include <AK/InlineLinkedList.h>
  4. #include <AK/OwnPtr.h>
  5. #include <AK/RefPtr.h>
  6. #include <AK/Vector.h>
  7. #include <Kernel/Arch/i386/CPU.h>
  8. #include <Kernel/KResult.h>
  9. #include <Kernel/UnixTypes.h>
  10. #include <Kernel/VM/Region.h>
  11. #include <Kernel/VirtualAddress.h>
  12. class Alarm;
  13. class FileDescription;
  14. class Process;
  15. class Region;
  16. class Thread;
  17. enum class ShouldUnblockThread {
  18. No = 0,
  19. Yes
  20. };
  21. struct SignalActionData {
  22. VirtualAddress handler_or_sigaction;
  23. u32 mask { 0 };
  24. int flags { 0 };
  25. };
  26. extern InlineLinkedList<Thread>* g_runnable_threads;
  27. extern InlineLinkedList<Thread>* g_nonrunnable_threads;
  28. class Thread : public InlineLinkedListNode<Thread> {
  29. friend class Process;
  30. friend class Scheduler;
  31. public:
  32. explicit Thread(Process&);
  33. ~Thread();
  34. static void initialize();
  35. static void finalize_dying_threads();
  36. static Vector<Thread*> all_threads();
  37. static bool is_thread(void*);
  38. int tid() const { return m_tid; }
  39. int pid() const;
  40. Process& process() { return m_process; }
  41. const Process& process() const { return m_process; }
  42. void finalize();
  43. enum State : u8 {
  44. Invalid = 0,
  45. Runnable,
  46. Running,
  47. Skip1SchedulerPass,
  48. Skip0SchedulerPasses,
  49. Dying,
  50. Dead,
  51. Stopped,
  52. BlockedLurking,
  53. BlockedSleep,
  54. BlockedWait,
  55. BlockedRead,
  56. BlockedWrite,
  57. BlockedSignal,
  58. BlockedSelect,
  59. BlockedConnect,
  60. BlockedReceive,
  61. BlockedSnoozing,
  62. };
  63. void did_schedule() { ++m_times_scheduled; }
  64. u32 times_scheduled() const { return m_times_scheduled; }
  65. bool is_stopped() const { return m_state == Stopped; }
  66. bool is_blocked() const
  67. {
  68. return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead || m_state == BlockedWrite || m_state == BlockedSignal || m_state == BlockedSelect;
  69. }
  70. bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
  71. u32 frame_ptr() const { return m_tss.ebp; }
  72. u32 stack_ptr() const { return m_tss.esp; }
  73. u16 selector() const { return m_far_ptr.selector; }
  74. TSS32& tss() { return m_tss; }
  75. State state() const { return m_state; }
  76. u32 ticks() const { return m_ticks; }
  77. pid_t waitee_pid() const { return m_waitee_pid; }
  78. void sleep(u32 ticks);
  79. void block(Thread::State);
  80. void block(Thread::State, FileDescription&);
  81. void unblock();
  82. void set_wakeup_time(u64 t) { m_wakeup_time = t; }
  83. u64 wakeup_time() const { return m_wakeup_time; }
  84. void snooze_until(Alarm&);
  85. KResult wait_for_connect(FileDescription&);
  86. const FarPtr& far_ptr() const { return m_far_ptr; }
  87. bool tick();
  88. void set_ticks_left(u32 t) { m_ticks_left = t; }
  89. u32 ticks_left() const { return m_ticks_left; }
  90. u32 kernel_stack_base() const { return m_kernel_stack_base; }
  91. u32 kernel_stack_for_signal_handler_base() const { return m_kernel_stack_for_signal_handler_region ? m_kernel_stack_for_signal_handler_region->vaddr().get() : 0; }
  92. void set_selector(u16 s) { m_far_ptr.selector = s; }
  93. void set_state(State);
  94. void send_signal(u8 signal, Process* sender);
  95. ShouldUnblockThread dispatch_one_pending_signal();
  96. ShouldUnblockThread dispatch_signal(u8 signal);
  97. bool has_unmasked_pending_signals() const;
  98. void terminate_due_to_signal(u8 signal);
  99. bool should_ignore_signal(u8 signal) const;
  100. FPUState& fpu_state() { return *m_fpu_state; }
  101. bool has_used_fpu() const { return m_has_used_fpu; }
  102. void set_has_used_fpu(bool b) { m_has_used_fpu = b; }
  103. void set_default_signal_dispositions();
  104. void push_value_on_stack(u32);
  105. void make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment);
  106. void make_userspace_stack_for_secondary_thread(void* argument);
  107. Thread* clone(Process&);
  108. // For InlineLinkedList
  109. Thread* m_prev { nullptr };
  110. Thread* m_next { nullptr };
  111. InlineLinkedList<Thread>* thread_list() { return m_thread_list; }
  112. void set_thread_list(InlineLinkedList<Thread>*);
  113. template<typename Callback>
  114. static void for_each_in_state(State, Callback);
  115. template<typename Callback>
  116. static void for_each_living(Callback);
  117. template<typename Callback>
  118. static void for_each_runnable(Callback);
  119. template<typename Callback>
  120. static void for_each_nonrunnable(Callback);
  121. template<typename Callback>
  122. static void for_each(Callback);
  123. static bool is_runnable_state(Thread::State state)
  124. {
  125. return state == Thread::State::Running || state == Thread::State::Runnable;
  126. }
  127. static InlineLinkedList<Thread>* thread_list_for_state(Thread::State state)
  128. {
  129. if (is_runnable_state(state))
  130. return g_runnable_threads;
  131. return g_nonrunnable_threads;
  132. }
  133. private:
  134. Process& m_process;
  135. int m_tid { -1 };
  136. TSS32 m_tss;
  137. OwnPtr<TSS32> m_tss_to_resume_kernel;
  138. FarPtr m_far_ptr;
  139. u32 m_ticks { 0 };
  140. u32 m_ticks_left { 0 };
  141. u64 m_wakeup_time { 0 };
  142. u32 m_times_scheduled { 0 };
  143. u32 m_pending_signals { 0 };
  144. u32 m_signal_mask { 0 };
  145. u32 m_kernel_stack_base { 0 };
  146. RefPtr<Region> m_kernel_stack_region;
  147. RefPtr<Region> m_kernel_stack_for_signal_handler_region;
  148. pid_t m_waitee_pid { -1 };
  149. RefPtr<FileDescription> m_blocked_description;
  150. timeval m_select_timeout;
  151. SignalActionData m_signal_action_data[32];
  152. Region* m_signal_stack_user_region { nullptr };
  153. Alarm* m_snoozing_alarm { nullptr };
  154. Vector<int> m_select_read_fds;
  155. Vector<int> m_select_write_fds;
  156. Vector<int> m_select_exceptional_fds;
  157. FPUState* m_fpu_state { nullptr };
  158. InlineLinkedList<Thread>* m_thread_list { nullptr };
  159. State m_state { Invalid };
  160. bool m_select_has_timeout { false };
  161. bool m_has_used_fpu { false };
  162. bool m_was_interrupted_while_blocked { false };
  163. };
  164. HashTable<Thread*>& thread_table();
  165. const char* to_string(Thread::State);
  166. template<typename Callback>
  167. inline void Thread::for_each_in_state(State state, Callback callback)
  168. {
  169. ASSERT_INTERRUPTS_DISABLED();
  170. for (auto* thread = thread_list_for_state(state)->head(); thread;) {
  171. auto* next_thread = thread->next();
  172. if (thread->state() == state)
  173. callback(*thread);
  174. thread = next_thread;
  175. }
  176. }
  177. template<typename Callback>
  178. inline void Thread::for_each_living(Callback callback)
  179. {
  180. ASSERT_INTERRUPTS_DISABLED();
  181. for (auto* thread = g_runnable_threads->head(); thread;) {
  182. auto* next_thread = thread->next();
  183. if (thread->state() != Thread::State::Dead && thread->state() != Thread::State::Dying)
  184. callback(*thread);
  185. thread = next_thread;
  186. }
  187. for (auto* thread = g_nonrunnable_threads->head(); thread;) {
  188. auto* next_thread = thread->next();
  189. if (thread->state() != Thread::State::Dead && thread->state() != Thread::State::Dying)
  190. callback(*thread);
  191. thread = next_thread;
  192. }
  193. }
  194. template<typename Callback>
  195. inline void Thread::for_each(Callback callback)
  196. {
  197. ASSERT_INTERRUPTS_DISABLED();
  198. for_each_runnable(callback);
  199. for_each_nonrunnable(callback);
  200. }
  201. template<typename Callback>
  202. inline void Thread::for_each_runnable(Callback callback)
  203. {
  204. ASSERT_INTERRUPTS_DISABLED();
  205. for (auto* thread = g_runnable_threads->head(); thread;) {
  206. auto* next_thread = thread->next();
  207. if (callback(*thread) == IterationDecision::Break)
  208. return;
  209. thread = next_thread;
  210. }
  211. }
  212. template<typename Callback>
  213. inline void Thread::for_each_nonrunnable(Callback callback)
  214. {
  215. ASSERT_INTERRUPTS_DISABLED();
  216. for (auto* thread = g_nonrunnable_threads->head(); thread;) {
  217. auto* next_thread = thread->next();
  218. if (callback(*thread) == IterationDecision::Break)
  219. return;
  220. thread = next_thread;
  221. }
  222. }