thread_i.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Copyright (c) 2017-2018 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef KERN_THREAD_I_H
  18. #define KERN_THREAD_I_H
  19. #include <stdalign.h>
  20. #include <stdbool.h>
  21. #include <kern/atomic.h>
  22. #include <kern/cpumap.h>
  23. #include <kern/list_types.h>
  24. #include <kern/perfmon_types.h>
  25. #include <kern/rcu_types.h>
  26. #include <kern/spinlock_types.h>
  27. #include <kern/turnstile_types.h>
  28. #include <machine/cpu.h>
  29. #include <machine/tcb.h>
  30. /*
  31. * Forward declarations.
  32. */
  33. struct sleepq;
  34. struct thread_runq;
  35. struct thread_fs_runq;
  36. /*
  37. * Thread flags.
  38. */
  39. #define THREAD_YIELD 0x1UL /* Must yield the processor ASAP */
  40. #define THREAD_DETACHED 0x2UL /* Resources automatically released on exit */
  41. /*
  42. * Scheduling data for a real-time thread.
  43. */
  44. struct thread_rt_data {
  45. struct list node;
  46. unsigned short time_slice;
  47. };
  48. /*
  49. * Scheduling data for a fair-scheduling thread.
  50. */
  51. struct thread_fs_data {
  52. struct list group_node;
  53. struct list runq_node;
  54. struct thread_fs_runq *fs_runq;
  55. unsigned long round;
  56. unsigned short weight;
  57. unsigned short work;
  58. };
  59. /*
  60. * Thread structure.
  61. *
  62. * Threads don't have their own lock. Instead, the associated run queue
  63. * lock is used for synchronization. A number of members are thread-local
  64. * and require no synchronization. Others must be accessed with atomic
  65. * instructions.
  66. *
  67. * Locking keys :
  68. * (r) run queue
  69. * (t) turnstile_td
  70. * (T) task
  71. * (j) join_lock
  72. * (a) atomic
  73. * (-) thread-local
  74. * ( ) read-only
  75. *
  76. * (*) The runq member is used to determine which run queue lock must be
  77. * held to serialize access to the relevant members. However, it is only
  78. * updated while the associated run queue is locked. As a result, atomic
  79. * reads are only necessary outside critical sections.
  80. */
  81. struct thread {
  82. alignas(CPU_L1_SIZE) struct tcb tcb; /* (r) */
  83. unsigned long nr_refs; /* (a) */
  84. unsigned long flags; /* (a) */
  85. /* Sleep/wake-up synchronization members */
  86. struct thread_runq *runq; /* (r,*) */
  87. bool in_runq; /* (r) */
  88. const void *wchan_addr; /* (r) */
  89. const char *wchan_desc; /* (r) */
  90. int wakeup_error; /* (r) */
  91. unsigned int state; /* (a,r) */
  92. /* Sleep queue available for lending */
  93. struct sleepq *priv_sleepq; /* (-) */
  94. /* Turnstile available for lending */
  95. struct turnstile *priv_turnstile; /* (-) */
  96. struct turnstile_td turnstile_td; /* (t) */
  97. /* True if priority must be propagated when preemption is reenabled */
  98. bool propagate_priority; /* (-) */
  99. /* Preemption level, preemption is enabled if 0 */
  100. unsigned short preempt_level; /* (-) */
  101. /* Pin level, migration is allowed if 0 */
  102. unsigned short pin_level; /* (-) */
  103. /* Interrupt level, in thread context if 0 */
  104. unsigned short intr_level; /* (-) */
  105. /* RCU per-thread data */
  106. struct rcu_reader rcu_reader; /* (-) */
  107. /* Processors on which this thread is allowed to run */
  108. struct cpumap cpumap; /* (r) */
  109. struct thread_sched_data user_sched_data; /* (r,t) */
  110. struct thread_sched_data real_sched_data; /* (r,t) */
  111. /*
  112. * True if the real scheduling data are not the user scheduling data.
  113. *
  114. * Note that it doesn't provide any information about priority inheritance.
  115. * A thread may be part of a priority inheritance chain without its
  116. * priority being boosted.
  117. */
  118. bool boosted; /* (r,t) */
  119. /* True if the thread is marked to suspend */
  120. bool suspend; /* (r) */
  121. union {
  122. struct thread_rt_data rt_data; /* (r) */
  123. struct thread_fs_data fs_data; /* (r) */
  124. };
  125. /*
  126. * Thread-specific data.
  127. *
  128. * TSD are reserved for application use.
  129. */
  130. #if CONFIG_THREAD_MAX_TSD_KEYS != 0
  131. void *tsd[CONFIG_THREAD_MAX_TSD_KEYS];
  132. #endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */
  133. /*
  134. * Members related to termination.
  135. *
  136. * The termination protocol is made of two steps :
  137. * 1/ The thread exits, thereby releasing its self reference, and
  138. * sets its state to dead before calling the scheduler.
  139. * 2/ Another thread must either already be joining, or join later.
  140. * When the thread reference counter drops to zero, the terminating
  141. * flag is set, and the joining thread is awoken, if any. After that,
  142. * the join operation polls the state until it sees the target thread
  143. * as dead, and then releases its resources.
  144. */
  145. struct thread *join_waiter; /* (j) */
  146. struct spinlock join_lock;
  147. bool terminating; /* (j) */
  148. struct task *task; /* (T) */
  149. struct list task_node; /* (T) */
  150. void *stack; /* (-) */
  151. char name[THREAD_NAME_SIZE]; /* ( ) */
  152. #ifdef CONFIG_PERFMON
  153. struct perfmon_td perfmon_td; /* ( ) */
  154. #endif
  155. };
  156. #define THREAD_ATTR_DETACHED 0x1
  157. void thread_terminate(struct thread *thread);
  158. /*
  159. * Flag access functions.
  160. */
  161. static inline void
  162. thread_set_flag(struct thread *thread, unsigned long flag)
  163. {
  164. atomic_or(&thread->flags, flag, ATOMIC_RELEASE);
  165. }
  166. static inline void
  167. thread_clear_flag(struct thread *thread, unsigned long flag)
  168. {
  169. atomic_and(&thread->flags, ~flag, ATOMIC_RELEASE);
  170. }
  171. static inline int
  172. thread_test_flag(struct thread *thread, unsigned long flag)
  173. {
  174. return (atomic_load(&thread->flags, ATOMIC_ACQUIRE) & flag) != 0;
  175. }
  176. #endif /* KERN_THREAD_I_H */