Thread.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #pragma once
  2. #include <Kernel/i386.h>
  3. #include <Kernel/KResult.h>
  4. #include <Kernel/LinearAddress.h>
  5. #include <Kernel/UnixTypes.h>
  6. #include <Kernel/VM/Region.h>
  7. #include <AK/AKString.h>
  8. #include <AK/InlineLinkedList.h>
  9. #include <AK/OwnPtr.h>
  10. #include <AK/RetainPtr.h>
  11. #include <AK/Vector.h>
  12. class Alarm;
  13. class FileDescriptor;
  14. class Process;
  15. class Region;
  16. enum class ShouldUnblockThread { No = 0, Yes };
  17. struct SignalActionData {
  18. LinearAddress handler_or_sigaction;
  19. dword mask { 0 };
  20. int flags { 0 };
  21. };
  22. class Thread : public InlineLinkedListNode<Thread> {
  23. friend class Process;
  24. friend class Scheduler;
  25. public:
  26. explicit Thread(Process&);
  27. ~Thread();
  28. static void initialize();
  29. static void finalize_dying_threads();
  30. static Vector<Thread*> all_threads();
  31. static bool is_thread(void*);
  32. int tid() const { return m_tid; }
  33. int pid() const;
  34. Process& process() { return m_process; }
  35. const Process& process() const { return m_process; }
  36. void finalize();
  37. enum State : byte {
  38. Invalid = 0,
  39. Runnable,
  40. Running,
  41. Skip1SchedulerPass,
  42. Skip0SchedulerPasses,
  43. Dying,
  44. Dead,
  45. Stopped,
  46. BlockedLurking,
  47. BlockedSleep,
  48. BlockedWait,
  49. BlockedRead,
  50. BlockedWrite,
  51. BlockedSignal,
  52. BlockedSelect,
  53. BlockedConnect,
  54. BlockedReceive,
  55. BlockedSnoozing,
  56. };
  57. void did_schedule() { ++m_times_scheduled; }
  58. dword times_scheduled() const { return m_times_scheduled; }
  59. bool is_stopped() const { return m_state == Stopped; }
  60. bool is_blocked() const
  61. {
  62. return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead || m_state == BlockedWrite || m_state == BlockedSignal || m_state == BlockedSelect;
  63. }
  64. bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
  65. dword frame_ptr() const { return m_tss.ebp; }
  66. dword stack_ptr() const { return m_tss.esp; }
  67. word selector() const { return m_far_ptr.selector; }
  68. TSS32& tss() { return m_tss; }
  69. State state() const { return m_state; }
  70. dword ticks() const { return m_ticks; }
  71. pid_t waitee_pid() const { return m_waitee_pid; }
  72. void sleep(dword ticks);
  73. void block(Thread::State);
  74. void block(Thread::State, FileDescriptor&);
  75. void unblock();
  76. void set_wakeup_time(qword t) { m_wakeup_time = t; }
  77. qword wakeup_time() const { return m_wakeup_time; }
  78. void snooze_until(Alarm&);
  79. KResult wait_for_connect(FileDescriptor&);
  80. const FarPtr& far_ptr() const { return m_far_ptr; }
  81. bool tick();
  82. void set_ticks_left(dword t) { m_ticks_left = t; }
  83. dword ticks_left() const { return m_ticks_left; }
  84. dword kernel_stack_base() const { return m_kernel_stack_region->laddr().get(); }
  85. dword kernel_stack_for_signal_handler_base() const { return (dword)m_kernel_stack_for_signal_handler; }
  86. void set_selector(word s) { m_far_ptr.selector = s; }
  87. void set_state(State s) { m_state = s; }
  88. void send_signal(byte signal, Process* sender);
  89. ShouldUnblockThread dispatch_one_pending_signal();
  90. ShouldUnblockThread dispatch_signal(byte signal);
  91. bool has_unmasked_pending_signals() const;
  92. void terminate_due_to_signal(byte signal);
  93. FPUState& fpu_state() { return *m_fpu_state; }
  94. bool has_used_fpu() const { return m_has_used_fpu; }
  95. void set_has_used_fpu(bool b) { m_has_used_fpu = b; }
  96. void set_default_signal_dispositions();
  97. void push_value_on_stack(dword);
  98. void make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment);
  99. void make_userspace_stack_for_secondary_thread(void* argument);
  100. Thread* clone(Process&);
  101. // For InlineLinkedList
  102. Thread* m_prev { nullptr };
  103. Thread* m_next { nullptr };
  104. template<typename Callback> static void for_each_in_state(State, Callback);
  105. template<typename Callback> static void for_each_living(Callback);
  106. template<typename Callback> static void for_each(Callback);
  107. private:
  108. Process& m_process;
  109. int m_tid { -1 };
  110. TSS32 m_tss;
  111. OwnPtr<TSS32> m_tss_to_resume_kernel;
  112. FarPtr m_far_ptr;
  113. dword m_ticks { 0 };
  114. dword m_ticks_left { 0 };
  115. qword m_wakeup_time { 0 };
  116. dword m_times_scheduled { 0 };
  117. dword m_pending_signals { 0 };
  118. dword m_signal_mask { 0 };
  119. RetainPtr<Region> m_kernel_stack_region;
  120. void* m_kernel_stack_for_signal_handler { nullptr };
  121. pid_t m_waitee_pid { -1 };
  122. RetainPtr<FileDescriptor> m_blocked_descriptor;
  123. timeval m_select_timeout;
  124. SignalActionData m_signal_action_data[32];
  125. Region* m_signal_stack_user_region { nullptr };
  126. Alarm* m_snoozing_alarm { nullptr };
  127. Vector<int> m_select_read_fds;
  128. Vector<int> m_select_write_fds;
  129. Vector<int> m_select_exceptional_fds;
  130. FPUState* m_fpu_state { nullptr };
  131. State m_state { Invalid };
  132. bool m_select_has_timeout { false };
  133. bool m_has_used_fpu { false };
  134. bool m_was_interrupted_while_blocked { false };
  135. };
  136. extern InlineLinkedList<Thread>* g_threads;
  137. const char* to_string(Thread::State);
  138. template<typename Callback>
  139. inline void Thread::for_each_in_state(State state, Callback callback)
  140. {
  141. ASSERT_INTERRUPTS_DISABLED();
  142. for (auto* thread = g_threads->head(); thread;) {
  143. auto* next_thread = thread->next();
  144. if (thread->state() == state)
  145. callback(*thread);
  146. thread = next_thread;
  147. }
  148. }
  149. template<typename Callback>
  150. inline void Thread::for_each_living(Callback callback)
  151. {
  152. ASSERT_INTERRUPTS_DISABLED();
  153. for (auto* thread = g_threads->head(); thread;) {
  154. auto* next_thread = thread->next();
  155. if (thread->state() != Thread::State::Dead && thread->state() != Thread::State::Dying)
  156. callback(*thread);
  157. thread = next_thread;
  158. }
  159. }
  160. template<typename Callback>
  161. inline void Thread::for_each(Callback callback)
  162. {
  163. ASSERT_INTERRUPTS_DISABLED();
  164. for (auto* thread = g_threads->head(); thread;) {
  165. auto* next_thread = thread->next();
  166. if (callback(*thread) == IterationDecision::Abort)
  167. return;
  168. thread = next_thread;
  169. }
  170. }