|
|
1.1 root 1: #ifndef _KERN_WAIT_QUEUE_H_
2: #define _KERN_WAIT_QUEUE_H_
3:
4: #include <kern/kern_types.h> /* for wait_queue_t */
5: #include <mach/sync_policy.h>
6:
7: #ifdef MACH_KERNEL_PRIVATE
8:
9: #include <kern/lock.h>
10: #include <kern/queue.h>
11:
12: /*
13: * wait_queue_t
14: * This is the definition of the common event wait queue
15: * that the scheduler APIs understand. It is used
16: * internally by the gerneralized event waiting mechanism
17: * (assert_wait), and also for items that maintain their
18: * own wait queues (such as ports and semaphores).
19: *
20: * It is not published to other kernel components. They
21: * can create wait queues by calling wait_queue_alloc.
22: *
23: * NOTE: Hardware locks are used to protect event wait
24: * queues since interrupt code is free to post events to
25: * them.
26: */
27: typedef struct wait_queue {
28: hw_lock_data_t wq_interlock; /* interlock */
29: unsigned int /* flags */
30: /* boolean_t */ wq_fifo:1, /* fifo wakeup policy? */
31: wq_issub:1, /* is waitq linked? */
32: :0; /* force to long boundary */
33: queue_head_t wq_queue; /* queue of elements */
34: } WaitQueue;
35:
36: /*
37: * wait_queue_sub_t
38: * This is the common definition for a subordinate wait queue.
39: * These can be linked as members/elements of multiple regular
40: * wait queues. They have an additional set of linkages to
41: * identify the linkage structures that point to them.
42: */
43: typedef struct wait_queue_sub {
44: WaitQueue wqs_wait_queue; /* our wait queue */
45: queue_head_t wqs_sublinks; /* links from sub perspective */
46: } WaitQueueSub;
47:
48: typedef WaitQueueSub *wait_queue_sub_t;
49:
50: #define WAIT_QUEUE_SUB_NULL ((wait_queue_sub_t)0)
51:
52:
53: /*
54: * wait_queue_element_t
55: * This structure describes the elements on an event wait
56: * queue. It is the common first fields in a thread shuttle
57: * and wait_queue_link_t. In that way, a wait queue can
58: * consist of both thread shuttle elements and links off of
59: * to other (subordinate) wait queues.
60: *
61: * WARNING: The first three fields of the thread shuttle
62: * definition does not use this definition yet. Any change in
63: * the layout here will have to be matched with a change there.
64: */
65: typedef struct wait_queue_element {
66: queue_chain_t wqe_links; /* link of elements on this queue */
67: wait_queue_t wqe_queue; /* queue this element is on */
68: event_t wqe_event; /* event this element is waiting for */
69: } *wait_queue_element_t;
70:
71: /*
72: * wait_queue_link_t
73: * Specialized wait queue element type for linking subordinate
74: * event waits queues onto a wait queue. In this way, an event
75: * can be constructed so that any thread waiting on any number
76: * of associated wait queues can handle the event, while letting
77: * the thread only be linked on the single wait queue it blocked on.
78: *
79: * One use: ports in multiple portsets. Each thread is queued up
80: * on the portset that it specifically blocked on during a receive
81: * operation. Each port's event queue links in all the portset
82: * event queues of which it is a member. An IPC event post associated
83: * with that port may wake up any thread from any of those portsets,
84: * or one that was waiting locally on the port itself.
85: */
86: typedef struct wait_queue_link {
87: struct wait_queue_element wql_element; /* element on master */
88: wait_queue_sub_t wql_subqueue; /* sub queue */
89: queue_chain_t wql_sublinks; /* element on sub */
90: } *wait_queue_link_t;
91:
92: #define WAIT_QUEUE_LINK_NULL ((wait_queue_link_t)0)
93:
94: #define wql_links wql_element.wqe_links
95: #define wql_queue wql_element.wqe_queue
96: #define wql_event wql_element.wqe_event
97:
98: extern int wait_queue_subordinate;
99: #define WAIT_QUEUE_SUBORDINATE &_wait_queue_subordinate
100:
101: extern void wait_queue_init(
102: wait_queue_t wait_queue,
103: int policy);
104:
105: extern kern_return_t wait_queue_link(
106: wait_queue_t wait_queue,
107: wait_queue_sub_t subordinate_queue);
108:
109: extern kern_return_t wait_queue_unlink(
110: wait_queue_t wait_queue,
111: wait_queue_sub_t subordinate_queue);
112: extern void wait_queue_unlink_one(
113: wait_queue_t wait_queue,
114: wait_queue_sub_t *subordinate_queue_pointer);
115:
116: extern boolean_t wait_queue_member_queue(
117: wait_queue_t wait_queue,
118: wait_queue_sub_t subordinate_queue);
119:
120: extern kern_return_t clear_wait_queue_internal(
121: thread_t thread,
122: int result);
123:
124: extern kern_return_t wait_queue_remove(
125: thread_t thread);
126:
127: #define wait_queue_assert_possible(thread) \
128: ((thread)->wait_queue == WAIT_QUEUE_NULL)
129:
130:
131: #define wait_queue_empty(wq) (queue_empty(&(wq)->wq_queue))
132:
133: #define wait_queue_held(wq) (hw_lock_held(&(wq)->wq_interlock))
134:
135: #define wait_queue_is_sub(wqs) ((wqs)->wqs_wait_queue.wq_issub)
136: #define wqs_lock(wqs) wait_queue_lock(&(wqs)->wqs_wait_queue)
137: #define wqs_unlock(wqs) wait_queue_unlock(&(wqs)->wqs_wait_queue)
138: #define wqs_lock_try(wqs) wait_queue__try_lock(&(wqs)->wqs_wait_queue)
139:
140: /******** Decomposed interfaces (to build higher level constructs) ***********/
141:
142: extern void wait_queue_lock(
143: wait_queue_t wait_queue);
144:
145: extern void wait_queue_unlock(
146: wait_queue_t wait_queue);
147:
148: extern boolean_t wait_queue_lock_try(
149: wait_queue_t wait_queue);
150:
151: /* assert intent to wait on a locked wait queue */
152: extern void wait_queue_assert_wait_locked(
153: wait_queue_t wait_queue,
154: event_t wait_event,
155: int interruptible,
156: boolean_t unlock);
157:
158: /* peek to see which thread would be chosen for a wakeup - but keep on queue */
159: extern void wait_queue_peek_locked(
160: wait_queue_t wait_queue,
161: event_t event,
162: thread_t *thread,
163: wait_queue_t *found_queue);
164:
165: /* peek to see which thread would be chosen for a wakeup - but keep on queue */
166: extern void wait_queue_pull_thread_locked(
167: wait_queue_t wait_queue,
168: thread_t thread,
169: boolean_t unlock);
170:
171: /* wakeup all threads waiting for a particular event on locked queue */
172: extern kern_return_t wait_queue_wakeup_one_locked(
173: wait_queue_t wait_queue,
174: event_t wake_event,
175: int result,
176: boolean_t unlock);
177:
178: /* wakeup one thread waiting for a particular event on locked queue */
179: extern kern_return_t wait_queue_wakeup_one_locked(
180: wait_queue_t wait_queue,
181: event_t wake_event,
182: int result,
183: boolean_t unlock);
184:
185: /* return the identity of a thread that is waiting for <wait_queue, event> */
186: extern thread_t wait_queue_recommend_locked(
187: wait_queue_t wait_queue,
188: event_t wake_event);
189:
190: /* return identity of a thread awakened for a particular <wait_queue,event> */
191: extern thread_t wait_queue_wakeup_identity_locked(
192: wait_queue_t wait_queue,
193: event_t wake_event,
194: int result,
195: boolean_t unlock);
196:
197: /* wakeup thread iff its still waiting for a particular event on locked queue */
198: extern kern_return_t wait_queue_wakeup_thread_locked(
199: wait_queue_t wait_queue,
200: event_t wake_event,
201: thread_t thread,
202: int result,
203: boolean_t unlock);
204:
205: #endif /* MACH_KERNEL_PRIVATE */
206:
207: extern wait_queue_t wait_queue_alloc(
208: int policy);
209:
210: extern void wait_queue_free(
211: wait_queue_t wait_queue);
212:
213: /******** Standalone interfaces (not a part of a higher construct) ************/
214:
215: /* assert intent to wait on <wait_queue,event> pair */
216: extern void wait_queue_assert_wait(
217: wait_queue_t wait_queue,
218: event_t wait_event,
219: boolean_t interruptible);
220:
221: /* wakeup the most appropriate thread waiting on <wait_queue,event> pair */
222: extern kern_return_t wait_queue_wakeup_one(
223: wait_queue_t wait_queue,
224: event_t wake_event,
225: int result);
226:
227: /* wakeup all the threads waiting on <wait_queue,event> pair */
228: extern kern_return_t wait_queue_wakeup_all(
229: wait_queue_t wait_queue,
230: event_t wake_event,
231: int result);
232:
233: /* wakeup a specified thread waiting iff waiting on <wait_queue,event> pair */
234: extern kern_return_t wait_queue_wakeup_thread(
235: wait_queue_t wait_queue,
236: event_t wake_event,
237: thread_t thread,
238: int result);
239:
240: #endif /* _KERN_WAIT_QUEUE_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.