|
|
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.