Branch data Line data Source code
1 : : /* wait queue for multiple threads on kernel objects */
2 : :
3 : : /*
4 : : * Copyright (c) 2015 Wind River Systems, Inc.
5 : : *
6 : : * SPDX-License-Identifier: Apache-2.0
7 : : */
8 : :
9 : : #ifndef ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
10 : : #define ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
11 : :
12 : : #include <zephyr/kernel_structs.h>
13 : : #include <zephyr/sys/dlist.h>
14 : : #include <zephyr/sys/rb.h>
15 : : #include <timeout_q.h>
16 : : #include <priority_q.h>
17 : :
18 : : #ifdef __cplusplus
19 : : extern "C" {
20 : : #endif
21 : :
22 : : #ifdef CONFIG_WAITQ_SCALABLE
23 : :
24 : : /**
25 : : * Walk all threads pending on a wait queue.
26 : : *
27 : : * @param wq Wait queue
28 : : * @param thread_ptr Thread pointer iterator variable
29 : : *
30 : : * @warning Do not remove thread from wait queue when using this macro.
31 : : */
32 : : #define _WAIT_Q_FOR_EACH(wq, thread_ptr) \
33 : : RB_FOR_EACH_CONTAINER(&(wq)->waitq.tree, thread_ptr, base.qnode_rb)
34 : :
35 : : /*
36 : : * RB_FOR_EACH_SAFE() does not (and cannot) exist so we are not
37 : : * able to provide _WAIT_Q_FOR_EACH_SAFE when CONFIG_WAITQ_SCALABLE=y.
38 : : */
39 : :
40 : : static inline void z_waitq_init(_wait_q_t *w)
41 : : {
42 : : w->waitq = (struct _priq_rb) {
43 : : .tree = {
44 : : .lessthan_fn = z_priq_rb_lessthan
45 : : }
46 : : };
47 : : }
48 : :
49 : : static inline struct k_thread *z_waitq_head(_wait_q_t *w)
50 : : {
51 : : return (struct k_thread *)rb_get_min(&w->waitq.tree);
52 : : }
53 : :
54 : : #else /* !CONFIG_WAITQ_SCALABLE: */
55 : :
56 : : /**
57 : : * Walk all threads pending on a wait queue.
58 : : *
59 : : * @param wq Wait queue
60 : : * @param thread_ptr Thread pointer iterator variable
61 : : *
62 : : * @warning Do not remove thread from wait queue when using this macro.
63 : : * Use @ref _WAIT_Q_FOR_EACH_SAFE instead if this is required.
64 : : */
65 : : #define _WAIT_Q_FOR_EACH(wq, thread_ptr) \
66 : : SYS_DLIST_FOR_EACH_CONTAINER(&((wq)->waitq), thread_ptr, \
67 : : base.qnode_dlist)
68 : :
69 : : /**
70 : : * Walk all threads pending on a wait queue.
71 : : *
72 : : * @note The iterator thread may be safely detached from the wait
73 : : * queue as part of the loop when using this macro.
74 : : *
75 : : * @warning `CONFIG_WAITQ_SCALABLE=n` is required to use this macro.
76 : : * Use it sparingly and make sure to have a fallback implementation
77 : : * which works when `CONFIG_WAITQ_SCALABLE=y`.
78 : : *
79 : : * @param wq Wait queue
80 : : * @param thread_ptr Thread pointer iterator variable
81 : : * @param loop_ptr Thread pointer variable used by loop
82 : : */
83 : : #define _WAIT_Q_FOR_EACH_SAFE(wq, thread_ptr, loop_ptr) \
84 : : SYS_DLIST_FOR_EACH_CONTAINER_SAFE(&((wq)->waitq), thread_ptr, \
85 : : loop_ptr, base.qnode_dlist)
86 : :
87 : 48 : static inline void z_waitq_init(_wait_q_t *w)
88 : : {
89 : 48 : sys_dlist_init(&w->waitq);
90 : 48 : }
91 : :
92 : 52 : static inline struct k_thread *z_waitq_head(_wait_q_t *w)
93 : : {
94 : 52 : return (struct k_thread *)sys_dlist_peek_head(&w->waitq);
95 : : }
96 : :
97 : : #endif /* !CONFIG_WAITQ_SCALABLE */
98 : :
99 : : #ifdef __cplusplus
100 : : }
101 : : #endif
102 : :
103 : : #endif /* ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_ */
|