thread.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. /*
  2. * Copyright (c) 2012-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. *
  18. * The thread module aims at providing an interface suitable to implement
  19. * POSIX scheduling policies. As such, it provides scheduling classes and
  20. * policies that closely match the standard ones. The "real-time" policies
  21. * (FIFO and RR) directly map the first-in first-out (SCHED_FIFO) and
  22. * round-robin (SCHED_RR) policies, while the "fair-scheduling" policy (FS)
  23. * can be used for the normal SCHED_OTHER policy. The idle policy is reserved
  24. * for idling kernel threads.
  25. *
  26. * By convention, the name of a kernel thread is built by concatenating the
  27. * kernel name and the name of the start function, separated with an underscore.
  28. * Threads that are bound to a processor also include the "/cpu_id" suffix.
  29. * For example, "x15_thread_balance/1" is the name of the inter-processor
  30. * balancer thread of the second processor.
  31. */
  32. #ifndef KERN_THREAD_H
  33. #define KERN_THREAD_H
  34. #include <assert.h>
  35. #include <stdbool.h>
  36. #include <stddef.h>
  37. #include <stdint.h>
  38. #include <stdnoreturn.h>
  39. #include <kern/atomic.h>
  40. #include <kern/bulletin.h>
  41. #include <kern/cpumap.h>
  42. #include <kern/init.h>
  43. #include <kern/cpumap.h>
  44. #include <kern/futex.h>
  45. #include <kern/kernel.h>
  46. #include <kern/kuid.h>
  47. #include <kern/list_types.h>
  48. #include <kern/macros.h>
  49. #include <kern/perfmon_types.h>
  50. #include <kern/rcu_types.h>
  51. #include <kern/spinlock_types.h>
  52. #include <kern/turnstile_types.h>
  53. #include <kern/types.h>
  54. #include <kern/unwind.h>
  55. #include <machine/cpu.h>
  56. #include <machine/tcb.h>
  57. /*
  58. * The global priority of a thread is meant to be compared against
  59. * another global priority to determine which thread has higher priority.
  60. */
  61. struct thread_sched_data
  62. {
  63. uint8_t sched_policy;
  64. uint8_t sched_class;
  65. uint16_t priority;
  66. uint32_t global_priority;
  67. };
  68. // Thread name buffer size.
  69. #define THREAD_NAME_SIZE 32
  70. // Forward declarations.
  71. struct sleepq;
  72. struct thread_runq;
  73. struct thread_fs_runq;
  74. // Thread flags.
  75. #define THREAD_YIELD 0x1UL // Must yield the processor ASAP.
  76. #define THREAD_DETACHED 0x2UL // Resources automatically released on exit.
  77. // Scheduling data for a real-time thread.
  78. struct thread_rt_data
  79. {
  80. struct list node;
  81. uint16_t time_slice;
  82. };
  83. // Scheduling data for a fair-scheduling thread.
  84. struct thread_fs_data
  85. {
  86. struct list group_node;
  87. struct list runq_node;
  88. struct thread_fs_runq *fs_runq;
  89. size_t round;
  90. uint16_t weight;
  91. uint16_t work;
  92. };
  93. /*
  94. * Thread structure.
  95. *
  96. * Threads don't have their own lock. Instead, the associated run queue
  97. * lock is used for synchronization. A number of members are thread-local
  98. * and require no synchronization. Others must be accessed with atomic
  99. * instructions.
  100. *
  101. * Locking keys :
  102. * (r) run queue
  103. * (t) turnstile_td
  104. * (T) task
  105. * (j) join_lock
  106. * (a) atomic
  107. * (-) thread-local
  108. * ( ) read-only
  109. *
  110. * (*) The runq member is used to determine which run queue lock must be
  111. * held to serialize access to the relevant members. However, it is only
  112. * updated while the associated run queue is locked. As a result, atomic
  113. * reads are only necessary outside critical sections.
  114. */
  115. struct thread
  116. {
  117. __cacheline_aligned struct tcb tcb; // (r)
  118. struct kuid_head kuid; // (a)
  119. unsigned long flags; // (a)
  120. // Sleep/wake-up synchronization members.
  121. struct thread_runq *runq; // (r,*)
  122. bool in_runq; // (r)
  123. const void *wchan_addr; // (r)
  124. const char *wchan_desc; // (r)
  125. int wakeup_error; // (r)
  126. uint32_t state; // (a,r)
  127. // Sleep queue available for lending.
  128. struct sleepq *priv_sleepq; // (-)
  129. // Turnstile available for lending.
  130. struct turnstile *priv_turnstile; // (-)
  131. struct turnstile_td turnstile_td; // (t)
  132. // True if priority must be propagated when preemption is reenabled.
  133. bool propagate_priority; // (-)
  134. // Preemption level, preemption is enabled if 0.
  135. uint16_t preempt_level; // (-)
  136. // Pin level, migration is allowed if 0.
  137. uint16_t pin_level; // (-)
  138. // Interrupt level, in thread context if 0.
  139. uint16_t intr_level; // (-)
  140. // Page fault enablement level. Page faults are enabled if 0.
  141. uint16_t pagefault_level;
  142. // RCU per-thread data,
  143. struct rcu_reader rcu_reader; // (-)
  144. // Processors on which this thread is allowed to run.
  145. struct cpumap cpumap; // (r)
  146. struct thread_sched_data user_sched_data; // (r,t)
  147. struct thread_sched_data real_sched_data; // (r,t)
  148. /*
  149. * True if the real scheduling data are not the user scheduling data.
  150. *
  151. * Note that it doesn't provide any information about priority inheritance.
  152. * A thread may be part of a priority inheritance chain without its
  153. * priority being boosted.
  154. */
  155. bool boosted; // (r,t)
  156. // True if the thread is marked to suspend.
  157. bool suspend; // (r)
  158. union
  159. {
  160. struct thread_rt_data rt_data; // (r)
  161. struct thread_fs_data fs_data; // (r)
  162. };
  163. /*
  164. * Members related to termination.
  165. *
  166. * The termination protocol is made of two steps :
  167. * 1/ The thread exits, thereby releasing its self reference, and
  168. * sets its state to dead before calling the scheduler.
  169. * 2/ Another thread must either already be joining, or join later.
  170. * When the thread reference counter drops to zero, the terminating
  171. * flag is set, and the joining thread is awoken, if any. After that,
  172. * the join operation polls the state until it sees the target thread
  173. * as dead, and then releases its resources.
  174. */
  175. struct thread *join_waiter; // (j)
  176. struct spinlock join_lock;
  177. bool terminating; // (j)
  178. struct task *task; // (T)
  179. struct list task_node; // (T)
  180. void *stack; // (-)
  181. char name[THREAD_NAME_SIZE]; // (T)
  182. #ifdef CONFIG_PERFMON
  183. struct perfmon_td perfmon_td; // ( )
  184. #endif
  185. struct unw_fixup_t *fixup; // (-)
  186. void *cur_port; // (-)
  187. struct task *xtask; // (-)
  188. struct futex_td *futex_td; // (-)
  189. struct bulletin dead_subs; // ( )
  190. };
  191. // Thread IPC message (TODO: Move to a specific header).
  192. struct thread_ipc_msg
  193. {
  194. uint32_t size;
  195. int op;
  196. union
  197. {
  198. char name[THREAD_NAME_SIZE];
  199. struct
  200. {
  201. void *map;
  202. uint32_t size;
  203. } cpumap;
  204. int id;
  205. };
  206. };
  207. // Thread IPC operations.
  208. enum
  209. {
  210. THREAD_IPC_GET_NAME,
  211. THREAD_IPC_SET_NAME,
  212. THREAD_IPC_GET_AFFINITY,
  213. THREAD_IPC_SET_AFFINITY,
  214. THREAD_IPC_GET_ID,
  215. };
  216. // Thread flags.
  217. #define THREAD_ATTR_DETACHED 0x1
  218. void thread_terminate (struct thread *thread);
  219. // Flag access functions.
  220. static inline void
  221. thread_set_flag (struct thread *thread, unsigned long flag)
  222. {
  223. atomic_or_rel (&thread->flags, flag);
  224. }
  225. static inline void
  226. thread_clear_flag (struct thread *thread, unsigned long flag)
  227. {
  228. atomic_and_rel (&thread->flags, ~flag);
  229. }
  230. static inline int
  231. thread_test_flag (struct thread *thread, unsigned long flag)
  232. {
  233. return ((atomic_load_acq (&thread->flags) & flag) != 0);
  234. }
  235. #define THREAD_KERNEL_PREFIX KERNEL_NAME "_"
  236. // Thread states.
  237. #define THREAD_RUNNING 0
  238. #define THREAD_SLEEPING 1
  239. #define THREAD_DEAD 2
  240. #define THREAD_SUSPENDED 3
  241. /*
  242. * Scheduling policies.
  243. *
  244. * The idle policy is reserved for the per-CPU idle threads.
  245. */
  246. #define THREAD_SCHED_POLICY_FIFO 0
  247. #define THREAD_SCHED_POLICY_RR 1
  248. #define THREAD_SCHED_POLICY_FS 2
  249. #define THREAD_SCHED_POLICY_IDLE 3
  250. #define THREAD_NR_SCHED_POLICIES 4
  251. // Real-time priority properties.
  252. #define THREAD_SCHED_RT_PRIO_MIN 0
  253. #define THREAD_SCHED_RT_PRIO_MAX 31
  254. // Fair-scheduling priority properties.
  255. #define THREAD_SCHED_FS_PRIO_MIN 0
  256. #define THREAD_SCHED_FS_PRIO_DEFAULT 20
  257. #define THREAD_SCHED_FS_PRIO_MAX 39
  258. // Thread creation attributes.
  259. struct thread_attr
  260. {
  261. const char *name;
  262. size_t flags;
  263. struct cpumap *cpumap;
  264. struct task *task;
  265. uint8_t policy;
  266. uint16_t priority;
  267. };
  268. /*
  269. * Initialize thread creation attributes with default values.
  270. *
  271. * It is guaranteed that these default values include :
  272. * - thread is joinable
  273. * - no processor affinity
  274. * - task is inherited from parent thread
  275. * - policy is fair-scheduling
  276. * - priority is fair-scheduling default
  277. * - no user stack
  278. *
  279. * If the policy is changed, the priority, if applicable, must be updated
  280. * as well.
  281. */
  282. static inline void
  283. thread_attr_init (struct thread_attr *attr, const char *name)
  284. {
  285. attr->name = name;
  286. attr->flags = 0;
  287. attr->cpumap = NULL;
  288. attr->task = NULL;
  289. attr->policy = THREAD_SCHED_POLICY_FS;
  290. attr->priority = THREAD_SCHED_FS_PRIO_DEFAULT;
  291. }
  292. static inline void
  293. thread_attr_set_detached (struct thread_attr *attr)
  294. {
  295. attr->flags |= THREAD_ATTR_DETACHED;
  296. }
  297. static inline void
  298. thread_attr_set_cpumap (struct thread_attr *attr, struct cpumap *cpumap)
  299. {
  300. attr->cpumap = cpumap;
  301. }
  302. static inline void
  303. thread_attr_set_task (struct thread_attr *attr, struct task *task)
  304. {
  305. attr->task = task;
  306. }
  307. static inline void
  308. thread_attr_set_policy (struct thread_attr *attr, uint8_t policy)
  309. {
  310. attr->policy = policy;
  311. }
  312. static inline void
  313. thread_attr_set_priority (struct thread_attr *attr, uint16_t priority)
  314. {
  315. attr->priority = priority;
  316. }
  317. /*
  318. * Thread entry point.
  319. *
  320. * Loaded TCBs are expected to call this function with interrupts disabled.
  321. */
  322. void thread_main (void (*fn) (void *), void *arg);
  323. // Initialization of the thread module on APs.
  324. void thread_ap_setup (void);
  325. /*
  326. * Create a thread.
  327. *
  328. * Creation attributes must be passed, but some of them may be NULL, in which
  329. * case the value is inherited from the caller. The name attribute must not be
  330. * NULL.
  331. *
  332. * If successful, and if the caller passed a non-NULL thread pointer, it is
  333. * filled with the address of the newly created thread.
  334. */
  335. int thread_create (struct thread **threadp, const struct thread_attr *attr,
  336. void (*fn) (void *), void *arg);
  337. // Terminate the calling thread.
  338. noreturn void thread_exit (void);
  339. // Wait for the given thread to terminate and release its resources.
  340. void thread_join (struct thread *thread);
  341. /*
  342. * Make the current thread sleep while waiting for an event.
  343. *
  344. * The interlock is used to synchronize the thread state with respect to
  345. * wake-ups, i.e. a wake-up request sent by another thread cannot be missed
  346. * if that thread is holding the interlock.
  347. *
  348. * As a special exception, threads that use preemption as a synchronization
  349. * mechanism can omit the interlock and pass a NULL pointer instead.
  350. * In any case, the preemption nesting level must strictly be one when calling
  351. * this function.
  352. *
  353. * The wait channel describes the reason why the thread is sleeping. The
  354. * address should refer to a relevant synchronization object, normally
  355. * containing the interlock, but not necessarily.
  356. *
  357. * When bounding the duration of the sleep, the caller must pass an absolute
  358. * time in ticks, and ETIMEDOUT is returned if that time is reached before
  359. * the thread is awoken.
  360. *
  361. * Implies a memory barrier.
  362. */
  363. void thread_sleep (struct spinlock *interlock, const void *wchan_addr,
  364. const char *wchan_desc);
  365. int thread_timedsleep (struct spinlock *interlock, const void *wchan_addr,
  366. const char *wchan_desc, uint64_t ticks);
  367. /*
  368. * Schedule a thread for execution on a processor.
  369. *
  370. * If the target thread is NULL, the calling thread, or already in the
  371. * running state, or in the suspended state, no action is performed and
  372. * EINVAL is returned.
  373. *
  374. * TODO Describe memory ordering with regard to thread_sleep().
  375. */
  376. int thread_wakeup (struct thread *thread);
  377. /*
  378. * Suspend a thread.
  379. *
  380. * A suspended thread may only be resumed by calling thread_resume().
  381. *
  382. * This operation is asynchronous, i.e. the caller must not expect the target
  383. * thread to be suspended on return.
  384. *
  385. * If attempting to suspend core system threads, or threads in the dead state,
  386. * or if the given thread is NULL, the request is ignored and EINVAL is
  387. * returned. If the target thread is already suspended, the call turns into
  388. * a no-op and merely returns success.
  389. */
  390. int thread_suspend (struct thread *thread);
  391. /*
  392. * Resume a thread.
  393. *
  394. * This call is equivalent to thread_wakeup(), with the exception that
  395. * it may also wake up suspended threads.
  396. */
  397. int thread_resume (struct thread *thread);
  398. // Suspend execution of the calling thread.
  399. void thread_delay (uint64_t ticks, bool absolute);
  400. /*
  401. * Start running threads on the local processor.
  402. *
  403. * Interrupts must be disabled when calling this function.
  404. */
  405. noreturn void thread_run_scheduler (void);
  406. /*
  407. * Make the calling thread release the processor.
  408. *
  409. * This call does nothing if preemption is disabled, or the scheduler
  410. * determines the caller should continue to run (e.g. it's currently the only
  411. * runnable thread).
  412. *
  413. * Implies a full memory barrier if a context switch occurred.
  414. */
  415. void thread_yield (void);
  416. // Report a scheduling interrupt from a remote processor.
  417. void thread_schedule_intr (void);
  418. /*
  419. * Report a periodic event on the current processor.
  420. *
  421. * Interrupts and preemption must be disabled when calling this function.
  422. */
  423. void thread_report_periodic_event (void);
  424. // Set thread scheduling parameters.
  425. void thread_setscheduler (struct thread *thread, uint8_t policy,
  426. uint16_t priority);
  427. /*
  428. * Variant used for priority inheritance.
  429. *
  430. * The caller must hold the turnstile thread data lock and no turnstile
  431. * locks when calling this function.
  432. */
  433. void thread_pi_setscheduler (struct thread *thread, uint8_t policy,
  434. uint16_t priority);
  435. static inline void
  436. thread_ref (struct thread *thread)
  437. {
  438. size_t nr_refs = atomic_add_rlx (&thread->kuid.nr_refs, 1);
  439. assert (nr_refs != (size_t)-1);
  440. }
  441. static inline void
  442. thread_unref (struct thread *thread)
  443. {
  444. size_t nr_refs = atomic_sub_acq_rel (&thread->kuid.nr_refs, 1);
  445. assert (nr_refs);
  446. if (nr_refs == 1)
  447. thread_terminate (thread);
  448. }
  449. static inline const void*
  450. thread_wchan_addr (const struct thread *thread)
  451. {
  452. return (thread->wchan_addr);
  453. }
  454. static inline const char*
  455. thread_wchan_desc (const struct thread *thread)
  456. {
  457. return (thread->wchan_desc);
  458. }
  459. // Return a character representation of the state of a thread.
  460. char thread_state_to_chr (uint32_t state);
  461. static inline const struct thread_sched_data*
  462. thread_get_user_sched_data (const struct thread *thread)
  463. {
  464. return (&thread->user_sched_data);
  465. }
  466. static inline const struct thread_sched_data*
  467. thread_get_real_sched_data (const struct thread *thread)
  468. {
  469. return (&thread->real_sched_data);
  470. }
  471. /*
  472. * If the caller requires the scheduling data to be stable, it
  473. * must lock one of the following objects :
  474. * - the containing run queue
  475. * - the per-thread turnstile data (turnstile_td)
  476. *
  477. * Both are locked when scheduling data are updated.
  478. */
  479. static inline uint8_t
  480. thread_user_sched_policy (const struct thread *thread)
  481. {
  482. return (thread_get_user_sched_data(thread)->sched_policy);
  483. }
  484. static inline uint8_t
  485. thread_user_sched_class (const struct thread *thread)
  486. {
  487. return (thread_get_user_sched_data(thread)->sched_class);
  488. }
  489. static inline uint16_t
  490. thread_user_priority (const struct thread *thread)
  491. {
  492. return (thread_get_user_sched_data(thread)->priority);
  493. }
  494. static inline uint32_t
  495. thread_user_global_priority (const struct thread *thread)
  496. {
  497. return (thread_get_user_sched_data(thread)->global_priority);
  498. }
  499. static inline uint8_t
  500. thread_real_sched_policy (const struct thread *thread)
  501. {
  502. return (thread_get_real_sched_data(thread)->sched_policy);
  503. }
  504. static inline uint8_t
  505. thread_real_sched_class (const struct thread *thread)
  506. {
  507. return (thread_get_real_sched_data(thread)->sched_class);
  508. }
  509. static inline uint16_t
  510. thread_real_priority (const struct thread *thread)
  511. {
  512. return (thread_get_real_sched_data(thread)->priority);
  513. }
  514. static inline uint32_t
  515. thread_real_global_priority (const struct thread *thread)
  516. {
  517. return (thread_get_real_sched_data(thread)->global_priority);
  518. }
  519. // Return a string representation of the scheduling class of a thread.
  520. const char* thread_sched_class_to_str (uint8_t sched_class);
  521. static inline struct tcb*
  522. thread_get_tcb (struct thread *thread)
  523. {
  524. return (&thread->tcb);
  525. }
  526. static inline struct thread*
  527. thread_from_tcb (struct tcb *tcb)
  528. {
  529. return (structof (tcb, struct thread, tcb));
  530. }
  531. static inline struct thread*
  532. thread_self (void)
  533. {
  534. return (thread_from_tcb (tcb_current ()));
  535. }
  536. static inline int
  537. thread_id (const struct thread *thread)
  538. {
  539. return ((int)thread->kuid.id);
  540. }
  541. /*
  542. * Main scheduler invocation call.
  543. *
  544. * Called on return from interrupt or when reenabling preemption.
  545. */
  546. void thread_schedule (void);
  547. // Sleep queue lending functions.
  548. static inline struct sleepq*
  549. thread_sleepq_lend (struct thread *self)
  550. {
  551. struct sleepq *sleepq = self->priv_sleepq;
  552. assert (sleepq);
  553. self->priv_sleepq = NULL;
  554. return (sleepq);
  555. }
  556. static inline void
  557. thread_sleepq_return (struct sleepq *sleepq)
  558. {
  559. assert (sleepq);
  560. assert (!thread_self()->priv_sleepq);
  561. thread_self()->priv_sleepq = sleepq;
  562. }
  563. // Turnstile lending functions.
  564. static inline struct turnstile*
  565. thread_turnstile_lend (void)
  566. {
  567. struct turnstile *turnstile = thread_self()->priv_turnstile;
  568. assert (turnstile);
  569. thread_self()->priv_turnstile = NULL;
  570. return (turnstile);
  571. }
  572. static inline void
  573. thread_turnstile_return (struct turnstile *turnstile)
  574. {
  575. assert (turnstile);
  576. assert (!thread_self()->priv_turnstile);
  577. thread_self()->priv_turnstile = turnstile;
  578. }
  579. static inline struct turnstile_td*
  580. thread_turnstile_td (struct thread *thread)
  581. {
  582. return (&thread->turnstile_td);
  583. }
  584. // Priority propagation functions.
  585. static inline bool
  586. thread_priority_propagation_needed (void)
  587. {
  588. return (thread_self()->propagate_priority);
  589. }
  590. static inline void
  591. thread_set_priority_propagation_needed (void)
  592. {
  593. thread_self()->propagate_priority = true;
  594. }
  595. void thread_propagate_priority (void);
  596. /*
  597. * Migration control functions.
  598. *
  599. * Functions that change the migration state are implicit compiler barriers.
  600. */
  601. static inline int
  602. thread_pinned (void)
  603. {
  604. return (thread_self()->pin_level != 0);
  605. }
  606. static void
  607. thread_pin_level (uint16_t *levelp)
  608. {
  609. ++*levelp;
  610. assert (*levelp);
  611. barrier ();
  612. }
  613. static inline void
  614. thread_pin (void)
  615. {
  616. thread_pin_level (&thread_self()->pin_level);
  617. }
  618. static inline void
  619. thread_unpin_level (uint16_t *levelp)
  620. {
  621. barrier ();
  622. assert (*levelp);
  623. --*levelp;
  624. }
  625. static inline void
  626. thread_unpin (void)
  627. {
  628. thread_unpin_level (&thread_self()->pin_level);
  629. }
  630. #define THREAD_PIN_GUARD() \
  631. CLEANUP (thread_pin_guard_fini) uint16_t __unused *UNIQ(tpg) = \
  632. ({ \
  633. uint16_t *p_ = &thread_self()->pin_level; \
  634. thread_pin_level (p_); \
  635. p_; \
  636. })
  637. static inline void
  638. thread_pin_guard_fini (void *ptr)
  639. {
  640. thread_unpin_level (*(uint16_t **)ptr);
  641. }
  642. /*
  643. * Preemption control functions.
  644. *
  645. * Functions that change the preemption state are implicit compiler barriers.
  646. */
  647. static inline int
  648. thread_preempt_enabled (void)
  649. {
  650. return (thread_self()->preempt_level == 0);
  651. }
  652. static inline void
  653. thread_preempt_disable (void)
  654. {
  655. struct thread *thread = thread_self ();
  656. ++thread->preempt_level;
  657. assert (thread->preempt_level);
  658. barrier ();
  659. }
  660. static inline void
  661. thread_preempt_enable_no_resched (void)
  662. {
  663. barrier ();
  664. struct thread *thread = thread_self ();
  665. assert (thread->preempt_level);
  666. --thread->preempt_level;
  667. /*
  668. * Don't perform priority propagation here, because this function is
  669. * called on return from interrupt, where the transient state may
  670. * incorrectly trigger it.
  671. */
  672. }
  673. static inline void
  674. thread_preempt_enable (void)
  675. {
  676. thread_preempt_enable_no_resched ();
  677. if (thread_priority_propagation_needed () &&
  678. thread_preempt_enabled ())
  679. thread_propagate_priority ();
  680. thread_schedule ();
  681. }
  682. static inline void
  683. thread_preempt_disable_intr_save (cpu_flags_t *flags)
  684. {
  685. thread_preempt_disable ();
  686. cpu_intr_save (flags);
  687. }
  688. static inline void
  689. thread_preempt_enable_intr_restore (cpu_flags_t flags)
  690. {
  691. cpu_intr_restore (flags);
  692. thread_preempt_enable ();
  693. }
  694. /*
  695. * Interrupt level control functions.
  696. *
  697. * Functions that change the interrupt level are implicit compiler barriers.
  698. */
  699. static inline bool
  700. thread_interrupted (void)
  701. {
  702. return (thread_self()->intr_level != 0);
  703. }
  704. static inline bool
  705. thread_check_intr_context (void)
  706. {
  707. return (thread_interrupted () && !cpu_intr_enabled () &&
  708. !thread_preempt_enabled ());
  709. }
  710. static inline void
  711. thread_intr_enter_level (uint16_t *ptr)
  712. {
  713. if (++*ptr == 1)
  714. thread_preempt_disable ();
  715. assert (*ptr);
  716. barrier ();
  717. }
  718. static inline void
  719. thread_intr_enter (void)
  720. {
  721. thread_intr_enter_level (&thread_self()->intr_level);
  722. }
  723. static inline void
  724. thread_intr_leave_level (uint16_t *ptr)
  725. {
  726. barrier ();
  727. assert (*ptr);
  728. if (--*ptr == 0)
  729. thread_preempt_enable_no_resched ();
  730. }
  731. static inline void
  732. thread_intr_leave (void)
  733. {
  734. thread_intr_leave_level (&thread_self()->intr_level);
  735. }
  736. static inline void
  737. thread_intr_guard_fini (void *ptr)
  738. {
  739. thread_intr_leave_level (*(uint16_t **)ptr);
  740. }
  741. #define THREAD_INTR_GUARD() \
  742. CLEANUP (thread_intr_guard_fini) uint16_t __unused *UNIQ(tig) = \
  743. ({ \
  744. uint16_t *p_ = &thread_self()->intr_level; \
  745. thread_intr_enter_level (p_); \
  746. p_; \
  747. })
  748. // RCU functions.
  749. static inline struct rcu_reader*
  750. thread_rcu_reader (struct thread *thread)
  751. {
  752. return (&thread->rcu_reader);
  753. }
  754. static inline const char*
  755. thread_name (const struct thread *thread)
  756. {
  757. return (thread->name);
  758. }
  759. #ifdef CONFIG_PERFMON
  760. static inline struct perfmon_td*
  761. thread_get_perfmon_td (struct thread *thread)
  762. {
  763. return (&thread->perfmon_td);
  764. }
  765. #endif
  766. // Page fault functions.
  767. static inline void
  768. thread_pagefault_enable (void)
  769. {
  770. --thread_self()->pagefault_level;
  771. }
  772. static inline void
  773. thread_pagefault_disable (void)
  774. {
  775. ++thread_self()->pagefault_level;
  776. }
  777. /*
  778. * Return the last CPU on which the thread has been scheduled.
  779. *
  780. * This call isn't synchronized, and the caller may obtain an outdated value.
  781. */
  782. uint32_t thread_cpu (const struct thread *thread);
  783. /*
  784. * Return the current state of the given thread.
  785. *
  786. * This call isn't synchronized, and the caller may obtain an outdated value.
  787. */
  788. uint32_t thread_state (const struct thread *thread);
  789. /*
  790. * Return true if the given thread is running.
  791. *
  792. * This call isn't synchronized, and the caller may obtain an outdated value.
  793. */
  794. bool thread_is_running (const struct thread *thread);
  795. // Get the CPU affinity mask of the specified thread.
  796. int thread_get_affinity (const struct thread *thread, struct cpumap *cpumap);
  797. // Set the CPU affinity mask for the specified thread.
  798. int thread_set_affinity (struct thread *thread, const struct cpumap *cpumap);
  799. // Look up a thread by its KUID.
  800. static inline struct thread*
  801. thread_by_kuid (uint32_t kuid)
  802. {
  803. return (kuid_find_type (kuid, struct thread, kuid, KUID_THREAD));
  804. }
  805. // Handle an IPC message on a thread capability.
  806. struct cap_iters;
  807. struct ipc_msg_data;
  808. ssize_t thread_handle_msg (struct thread *thread, struct cap_iters *src,
  809. struct cap_iters *dst, struct ipc_msg_data *data);
  810. /*
  811. * This init operation provides :
  812. * - a dummy thread context for the BSP, allowing the use of thread_self()
  813. */
  814. INIT_OP_DECLARE (thread_setup_booter);
  815. /*
  816. * This init operation provides :
  817. * - same as thread_setup_booter
  818. * - BSP run queue initialization
  819. */
  820. INIT_OP_DECLARE (thread_bootstrap);
  821. /*
  822. * This init operation provides :
  823. * - thread creation
  824. * - module fully initialized
  825. */
  826. INIT_OP_DECLARE (thread_setup);
  827. #endif