2 * Copyright (c) 2017 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 #include <mach/mach_types.h>
33 #include <mach/kern_return.h>
34 #include <sys/cdefs.h>
37 #define TURNSTILE_MAX_HOP_DEFAULT (10)
38 struct turnstile_stats
{
39 uint64_t ts_priority_propagation
;
40 uint64_t ts_no_inheritor
;
41 uint64_t ts_thread_runnable
;
42 uint64_t ts_no_priority_change_required
;
43 uint64_t ts_above_ui_pri_change
;
44 uint64_t ts_no_turnstile
;
49 #include <kern/queue.h>
50 #include <sys/queue.h>
51 #include <kern/waitq.h>
52 #include <kern/priority_queue.h>
53 #include <os/refcnt.h>
54 #include <kern/assert.h>
55 #include <kern/kern_types.h>
56 #include <kern/mpsc_queue.h>
57 #include <kern/locks.h>
60 * turnstile_type_t : Indicates the type of primitive the turnstile is associated with
61 * Please populate turnstile_promote_policy array if a new type is added here.
63 typedef enum __attribute__((packed
)) turnstile_type
{
65 TURNSTILE_KERNEL_MUTEX
= 1,
67 TURNSTILE_PTHREAD_MUTEX
= 3,
68 TURNSTILE_SYNC_IPC
= 4,
69 TURNSTILE_WORKLOOPS
= 5,
72 TURNSTILE_SLEEP_INHERITOR
= 8,
73 TURNSTILE_TOTAL_TYPES
= 9,
77 * For each type of turnstile, following are the type of
80 * TURNSTILE_KERNEL_MUTEX
81 * Interlock: kernel mutex interlock.
83 * Lock order: turnstile lock, thread lock.
86 * Interlock: ulocks interlock.
88 * Lock order: turnstile lock, thread lock.
90 * TURNSTILE_PTHREAD_MUTEX
91 * Interlock: pthread mtx interlock.
93 * Lock order: turnstile lock, thread lock.
96 * Interlock: port's mqueue lock
97 * Inheritor: turnstile (of port in which we are enqueued or WL turnstile.
98 * Lock order: Our turnstile, then turnstile of the port we are enqueued in.
99 * Port circularity will make sure there is never a cycle formation
100 * and lock order is maintained.
102 * TURNSTILE_WORKLOOPS
105 * - wq lock when "filt_wlworkq_interlock_needed() is true"
106 * Inheritor: thread, turnstile (of workq)
107 * Lock order: turnstile lock, thread lock
108 * WL turnstile lock, Workq turnstile lock
111 * Interlock: workqueue lock
113 * Lock order: turnstile lock, thread lock.
116 * Interlock: the knote lock
117 * Inheritor: WL turnstile
119 * TURNSTILE_SLEEP_INHERITOR
120 * Interlock: turnstile_htable bucket spinlock.
121 * Inheritor: threads.
122 * Lock order: turnstile lock, thread lock.
126 typedef enum __attribute__((flag_enum
)) turnstile_promote_policy
{
127 TURNSTILE_PROMOTE_NONE
= 0,
128 TURNSTILE_KERNEL_PROMOTE
= 0x1,
129 TURNSTILE_USER_PROMOTE
= 0x2,
130 TURNSTILE_USER_IPC_PROMOTE
= 0x4,
131 } turnstile_promote_policy_t
;
133 typedef enum __attribute__((flag_enum
)) turnstile_hash_lock_policy
{
134 TURNSTILE_HASH_LOCK_POLICY_NONE
= 0,
135 TURNSTILE_IRQ_UNSAFE_HASH
= 0x1,
136 TURNSTILE_LOCKED_HASH
= 0x2,
137 } turnstile_hash_lock_policy_t
;
140 * Turnstile state flags
142 * The turnstile state flags represent the current ownership of a turnstile.
143 * The supported flags are:
144 * - TURNSTILE_STATE_THREAD : Turnstile is attached to a thread
145 * - TURNSTILE_STATE_FREELIST : Turnstile is hanging off the freelist of another turnstile
146 * - TURNSTILE_STATE_HASHTABLE : Turnstile is in the global hash table as the turnstile for a primitive
147 * - TURNSTILE_STATE_PROPRIETOR : Turnstile is attached to a proprietor
149 * The flag updates are done while holding the primitive interlock.
152 #define TURNSTILE_STATE_THREAD 0x1
153 #define TURNSTILE_STATE_FREELIST 0x2
154 #define TURNSTILE_STATE_HASHTABLE 0x4
155 #define TURNSTILE_STATE_PROPRIETOR 0x8
157 /* Helper macros to set/unset turnstile state flags */
158 #if DEVELOPMENT || DEBUG
160 #define turnstile_state_init(ts, state) \
162 ts->ts_state = state; \
165 #define turnstile_state_add(ts, state) \
167 assert((ts->ts_state & (state)) == 0); \
168 ts->ts_state |= state; \
171 #define turnstile_state_remove(ts, state) \
173 assert(ts->ts_state & (state)); \
174 ts->ts_state &= ~(state); \
177 #else /* DEVELOPMENT || DEBUG */
179 #define turnstile_state_init(ts, state) \
184 #define turnstile_state_add(ts, state) \
189 #define turnstile_state_remove(ts, state) \
194 #endif /* DEVELOPMENT || DEBUG */
200 * Turnstile update flags
202 * TURNSTILE_IMMEDIATE_UPDATE
203 * When passed to turnstile_update_inheritor
204 * update the inheritor of the turnstile in
207 * TURNSTILE_DELAYED_UPDATE
208 * When passed to turnstile_update_inheritor
209 * it stashed the inheritor on the thread and
210 * turnstile's inheritor is updated in
213 * TURNSTILE_INHERITOR_THREAD
214 * The turnstile inheritor is of type thread.
216 * TURNSTILE_INHERITOR_TURNSTILE
217 * The turnstile inheritor is of type turnstile.
219 * TURNSTILE_INHERITOR_WORKQ
220 * The turnstile inheritor is of type workqueue
222 * TURNSTILE_INHERITOR_NEEDS_PRI_UPDATE
223 * The inheritor needs a chain priority update.
225 * TURNSTILE_NEEDS_PRI_UPDATE
226 * Current turnstile needs a chain priority update.
228 * Locking order for passing thread and turnstile as inheritor
230 * Thread as an inheritor:
231 * When thread is passed as an inheritor of a turnstile
232 * turnstile lock is taken and then thread lock.
234 * Turnstile as in inheritor:
235 * When turnstile (T1) is passed as an inheritor of
236 * a turnstile (T2), turnstile lock of T2 is taken
237 * and then turnstile lock of T1 is taken.
239 * Caution: While passing turnstile as an inheritor, its
240 * job of the adopter to make sure that there is no
243 typedef enum __attribute__((flag_enum
)) __attribute__((packed
)) turnstile_update_flags
{
244 TURNSTILE_UPDATE_FLAGS_NONE
= 0,
245 TURNSTILE_IMMEDIATE_UPDATE
= 0x1,
246 TURNSTILE_DELAYED_UPDATE
= 0x2,
247 TURNSTILE_INHERITOR_THREAD
= 0x4,
248 TURNSTILE_INHERITOR_TURNSTILE
= 0x8,
249 TURNSTILE_INHERITOR_NEEDS_PRI_UPDATE
= 0x10,
250 TURNSTILE_NEEDS_PRI_UPDATE
= 0x20,
251 TURNSTILE_INHERITOR_WORKQ
= 0x40,
252 TURNSTILE_UPDATE_BOOST
= 0x80,
253 } turnstile_update_flags_t
;
255 #define TURNSTILE_NULL ((struct turnstile *)0)
257 typedef void * turnstile_inheritor_t
;
259 #define TURNSTILE_INHERITOR_NULL NULL
261 #ifdef XNU_KERNEL_PRIVATE
263 /* Turnstile stats update flags
265 * TSU_TURNSTILE_BLOCK_COUNT
266 * thread blocking on turnstile waitq, increment global
267 * thread block on turnstile count.
269 * TSU_REGULAR_WAITQ_BLOCK_COUNT
270 * thread blocking on regular waitq, increment global
271 * thread block on regular waitq count.
273 * TSU_PRI_PROPAGATION
274 * turnstile propagation update stopped at nth hop, update
275 * priority change count for nth element in stats array.
278 * turnstile propagation update stopped due to turnstile
279 * not having an inheritor after nth hop, update the no
280 * inheritor count for nth element in the stats array.
283 * turnstile propagation update stopped due to thread
284 * not blocked on a turnstile waitq after nth hop, update
285 * the no turnstile count for the nth element in the stats
288 * TSU_NO_PRI_CHANGE_NEEDED
289 * turnstile propagation update stopped due to thread or
290 * turnstile having the correct priority or not blocked.
291 * update the no priority change count for the nth element
292 * in the stats array.
294 * TSU_THREAD_RUNNABLE
295 * turnstile propagation update stopped due to thread
296 * being runnable, update the thread runnable count for
297 * the nth element in the stats array.
299 * TSU_ABOVE_UI_PRI_CHANGE
300 * turnstile propagation caused an above UI priority change.
302 typedef enum __attribute__((flag_enum
)) turnstile_stats_update_flags
{
304 TSU_TURNSTILE_BLOCK_COUNT
= 0x1,
305 TSU_REGULAR_WAITQ_BLOCK_COUNT
= 0x2,
306 TSU_PRI_PROPAGATION
= 0x4,
307 TSU_NO_INHERITOR
= 0x8,
308 TSU_NO_TURNSTILE
= 0x10,
309 TSU_NO_PRI_CHANGE_NEEDED
= 0x20,
310 TSU_THREAD_RUNNABLE
= 0x40,
311 TSU_ABOVE_UI_PRI_CHANGE
= 0x80,
312 TSU_THREAD_ARG
= 0x100,
313 TSU_TURNSTILE_ARG
= 0x200,
314 TSU_BOOST_ARG
= 0x400,
315 } turnstile_stats_update_flags_t
;
317 SLIST_HEAD(turnstile_list
, turnstile
);
320 struct waitq ts_waitq
; /* waitq embedded in turnstile */
321 turnstile_inheritor_t ts_inheritor
; /* thread/turnstile inheriting the priority (IL, WL) */
323 struct turnstile_list ts_free_turnstiles
; /* turnstile free list (IL) */
324 SLIST_ENTRY(turnstile
) ts_free_elm
; /* turnstile free list element (IL) */
326 struct priority_queue_sched_max ts_inheritor_queue
; /* Queue of turnstile with us as an inheritor (WL) */
328 struct priority_queue_entry_sched ts_inheritor_links
; /* Inheritor queue links */
329 struct mpsc_queue_chain ts_deallocate_link
; /* thread deallocate link */
331 SLIST_ENTRY(turnstile
) ts_htable_link
; /* linkage for turnstile in global hash table */
332 uintptr_t ts_proprietor
; /* hash key lookup turnstile (IL) */
333 os_refcnt_t ts_refcount
; /* reference count for turnstiles */
334 _Atomic
uint32_t ts_type_gencount
; /* gen count used for priority chaining (IL), type of turnstile (IL) */
335 uint32_t ts_port_ref
; /* number of explicit refs from ports on send turnstile */
336 turnstile_update_flags_t ts_inheritor_flags
; /* flags for turnstile inheritor (IL, WL) */
337 uint8_t ts_priority
; /* priority of turnstile (WL) */
339 #if DEVELOPMENT || DEBUG
340 uint8_t ts_state
; /* current state of turnstile (IL) */
341 queue_chain_t ts_global_elm
; /* global turnstile chain */
342 thread_t ts_thread
; /* thread the turnstile is attached to */
343 thread_t ts_prev_thread
; /* thread the turnstile was attached before donation */
347 #define waitq_to_turnstile(waitq) __container_of(waitq, struct turnstile, ts_waitq)
349 /* IL - interlock, WL - turnstile lock i.e. waitq lock */
351 #define TURNSTILE_PROPRIETOR_NULL 0ul
354 * Name: turnstiles_init
356 * Description: Initialize turnstile sub system.
363 turnstiles_init(void);
366 * Name: turnstile_alloc
368 * Description: Allocate a turnstile.
373 * turnstile on Success.
376 turnstile_alloc(void);
379 * Name: turnstile_destroy
381 * Description: Deallocates the turnstile.
389 turnstile_destroy(struct turnstile
*turnstile
);
392 * Name: turnstile_reference
394 * Description: Take a reference on the turnstile.
401 turnstile_reference(struct turnstile
*turnstile
);
404 * Name: turnstile_deallocate
406 * Description: Drop a reference on the turnstile.
407 * Destroy the turnstile if the last ref.
414 turnstile_deallocate(struct turnstile
*turnstile
);
417 * Name: turnstile_waitq_add_thread_priority_queue
419 * Description: add thread to the turnstile waitq
424 * Conditions: waitq locked
427 turnstile_waitq_add_thread_priority_queue(
432 * Name: turnstile_deallocate_safe
434 * Description: Drop a reference on the turnstile safely without triggering zfree.
441 turnstile_deallocate_safe(struct turnstile
*turnstile
);
444 * Name: turnstile_recompute_priority_locked
446 * Description: Update turnstile priority based
447 * on highest waiter thread and highest blocking
452 * Returns: TRUE: if the turnstile priority changed and needs propagation.
453 * FALSE: if the turnstile priority did not change or it does not need propagation.
455 * Condition: turnstile locked
458 turnstile_recompute_priority_locked(
459 struct turnstile
*turnstile
);
462 * Name: turnstile_recompute_priority
464 * Description: Update turnstile priority based
465 * on highest waiter thread and highest blocking
470 * Returns: TRUE: if the turnstile priority changed and needs propagation.
471 * FALSE: if the turnstile priority did not change or it does not need propagation.
474 turnstile_recompute_priority(
475 struct turnstile
*turnstile
);
478 * Name: turnstile_workq_proprietor_of_max_turnstile
480 * Description: Returns the highest priority and proprietor of a turnstile
481 * pushing on a workqueue turnstile.
483 * This will not return waiters that are at priority
484 * MAXPRI_THROTTLE or lower.
489 * Priority of the max entry, or 0
490 * Pointer to the max entry proprietor
493 turnstile_workq_proprietor_of_max_turnstile(
494 struct turnstile
*turnstile
,
495 uintptr_t *proprietor
);
498 * Name: turnstile_workloop_pusher_info
500 * Description: Returns the priority of the turnstile push for a workloop,
501 * and the thread or knote responsible for this push.
503 * Args: workloop turnstile
506 * Priority of the push or 0
507 * Thread (with a +1 reference) with that push or THREAD_NULL.
508 * Port (with a +1 reference) with that push, or IP_NULL.
509 * Sync IPC knote with the highest push (or NULL)
512 turnstile_workloop_pusher_info(
513 struct turnstile
*turnstile
,
516 struct knote
**knote_out
);
519 * Name: turnstile_cleanup
521 * Description: Update priority of a turnstile inheritor
524 * Args: inheritor and flags passed on thread struct.
529 turnstile_cleanup(void);
532 * Name: turnstile_update_thread_priority_chain
534 * Description: Priority of a thread blocked on a turnstile
535 * has changed, update the turnstile priority.
537 * Arg1: thread: thread whose priority has changed.
542 turnstile_update_thread_priority_chain(thread_t thread
);
545 * Name: turnstile_update_inheritor_locked
547 * Description: Update the inheritor of the turnstile and boost the
548 * inheritor, called with turnstile locked.
552 * Implicit arg: new inheritor value is stashed in current thread's struct
555 * old inheritor reference is returned on current thread's struct.
558 turnstile_update_inheritor_locked(struct turnstile
*turnstile
);
561 * Name: thread_get_inheritor_turnstile_base_priority
563 * Description: Get the max base priority of all the inheritor turnstiles
567 * Returns: Max base priority of all the inheritor turnstiles.
569 * Condition: thread locked
572 thread_get_inheritor_turnstile_base_priority(thread_t thread
);
575 * Name: thread_get_inheritor_turnstile_sched_priority
577 * Description: Get the max sched priority of all the inheritor turnstiles
581 * Returns: Max sched priority of all the inheritor turnstiles.
583 * Condition: thread locked
586 thread_get_inheritor_turnstile_sched_priority(thread_t thread
);
589 * Name: thread_get_waiting_turnstile
591 * Description: Get the turnstile if the thread is waiting on a turnstile.
595 * Returns: turnstile: if the thread is blocked on a turnstile.
596 * TURNSTILE_NULL: otherwise.
598 * Condition: thread locked.
601 thread_get_waiting_turnstile(thread_t thread
);
604 * Name: turnstile_lookup_by_proprietor
606 * Description: Get turnstile for a proprietor from global
610 * Arg2: turnstile_type_t type
612 * Returns: turnstile: if the proprietor has a turnstile.
613 * TURNSTILE_NULL: otherwise.
615 * Condition: proprietor interlock held.
618 turnstile_lookup_by_proprietor(uintptr_t proprietor
, turnstile_type_t type
);
621 * Name: turnstile_has_waiters
623 * Description: returns if there are waiters on the turnstile
625 * Arg1: turnstile: turnstile
627 * Returns: TRUE if there are waiters, FALSE otherwise.
631 turnstile_has_waiters(struct turnstile
*turnstile
);
634 * Name: turnstile_stats_update
636 * Description: Function to update turnstile stats for dev kernel.
638 * Arg1: hops : number of thread hops in priority propagation
639 * Arg2: flags : turnstile stats update flags
640 * Arg3: inheritor: inheritor
645 turnstile_stats_update(
646 int hop __assert_only
,
647 turnstile_stats_update_flags_t flags __assert_only
,
648 turnstile_inheritor_t inheritor __assert_only
);
650 #if DEVELOPMENT || DEBUG
652 #define SYSCTL_TURNSTILE_TEST_USER_DEFAULT 1
653 #define SYSCTL_TURNSTILE_TEST_USER_HASHTABLE 2
654 #define SYSCTL_TURNSTILE_TEST_KERNEL_DEFAULT 3
655 #define SYSCTL_TURNSTILE_TEST_KERNEL_HASHTABLE 4
657 /* Functions used by debug test primitive exported by sysctls */
659 tstile_test_prim_lock(int val
);
662 tstile_test_prim_unlock(int val
);
665 turnstile_get_boost_stats_sysctl(void *req
);
667 turnstile_get_unboost_stats_sysctl(void *req
);
668 #endif /* DEVELOPMENT || DEBUG */
669 #endif /* XNU_KERNEL_PRIVATE */
674 * Name: turnstile_hash_bucket_lock
676 * Description: locks the spinlock associated with proprietor's bucket.
677 * if proprietor is specified the index for the hash will be
678 * recomputed and returned in index_proprietor,
679 * otherwise the value save in index_proprietor is used as index.
682 * Arg1: proprietor (key) for hashing
683 * Arg2: index for proprietor in the hash
684 * Arg3: turnstile type
686 * Returns: old value of irq if irq were disabled before acquiring the lock.
689 turnstile_hash_bucket_lock(uintptr_t proprietor
, uint32_t *index_proprietor
, turnstile_type_t type
);
692 * Name: turnstile_hash_bucket_unlock
694 * Description: unlocks the spinlock associated with proprietor's bucket.
695 * if proprietor is specified the index for the hash will be
696 * recomputed and returned in index_proprietor,
697 * otherwise the value save in index_proprietor is used as index.
700 * Arg1: proprietor (key) for hashing
701 * Arg2: index for proprietor in the hash
702 * Arg3: turnstile type
703 * Arg4: irq value returned by turnstile_hash_bucket_lock
707 turnstile_hash_bucket_unlock(uintptr_t proprietor
, uint32_t *index_proprietor
, turnstile_type_t type
, unsigned s
);
710 * Name: turnstile_prepare
712 * Description: Transfer current thread's turnstile to primitive or it's free turnstile list.
713 * Function is called holding the interlock (spinlock) of the primitive.
714 * The turnstile returned by this function is safe to use untill the thread calls turnstile_complete.
715 * When no turnstile is provided explicitly, the calling thread will not have a turnstile attached to
716 * it untill it calls turnstile_complete.
720 * Arg2: pointer in primitive struct to store turnstile
721 * Arg3: turnstile to use instead of taking it from thread.
722 * Arg4: type of primitive
729 uintptr_t proprietor
,
730 struct turnstile
**tstore
,
731 struct turnstile
*turnstile
,
732 turnstile_type_t type
);
735 * Name: turnstile_complete
737 * Description: Transfer the primitive's turnstile or from it's freelist to current thread.
738 * Function is called holding the interlock (spinlock) of the primitive.
739 * Current thread will have a turnstile attached to it after this call.
743 * Arg2: pointer in primitive struct to update turnstile
744 * Arg3: pointer to store the returned turnstile instead of attaching it to thread
745 * Arg4: type of primitive
752 uintptr_t proprietor
,
753 struct turnstile
**tstore
,
754 struct turnstile
**turnstile
,
755 turnstile_type_t type
);
758 * Name: turnstile_update_inheritor
760 * Description: Update the inheritor of the turnstile and boost the
761 * inheritor. It will take a thread reference on the inheritor.
762 * Called with the interlock of the primitive held.
767 * Arg3: flags - TURNSTILE_DELAYED_UPDATE - update will happen later in assert_wait
770 * old inheritor reference is stashed on current thread's struct.
773 turnstile_update_inheritor(
774 struct turnstile
*turnstile
,
775 turnstile_inheritor_t new_inheritor
,
776 turnstile_update_flags_t flags
);
778 typedef enum turnstile_update_complete_flags
{
779 TURNSTILE_INTERLOCK_NOT_HELD
= 0x1,
780 TURNSTILE_INTERLOCK_HELD
= 0x2,
781 } turnstile_update_complete_flags_t
;
784 * Name: turnstile_update_inheritor_complete
786 * Description: Update turnstile inheritor's priority and propagate the
787 * priority if the inheritor is blocked on a turnstile.
788 * Consumes thread ref of old inheritor returned by
789 * turnstile_update_inheritor. Recursive priority update
790 * will only happen when called with interlock dropped.
794 * Arg2: interlock held
799 turnstile_update_inheritor_complete(
800 struct turnstile
*turnstile
,
801 turnstile_update_complete_flags_t flags
);
805 * Name: turnstile_kernel_update_inheritor_on_wake_locked
807 * Description: Set thread as the inheritor of the turnstile and
808 * boost the inheritor.
811 * Arg2: new_inheritor
814 * Called with turnstile locked
817 turnstile_kernel_update_inheritor_on_wake_locked(
818 struct turnstile
*turnstile
,
819 turnstile_inheritor_t new_inheritor
,
820 turnstile_update_flags_t flags
);
823 * Internal KPI for sleep_with_inheritor, wakeup_with_inheritor, change_sleep_inheritor
824 * meant to allow specifing the turnstile type to use to have different policy
825 * on how to push on the inheritor.
827 * Differently from the "standard" KPI in locks.h these are meant to be used only
828 * if you know what you are doing with turnstile.
832 lck_mtx_sleep_with_inheritor_and_turnstile_type(lck_mtx_t
*lock
, lck_sleep_action_t lck_sleep_action
, event_t event
, thread_t inheritor
, wait_interrupt_t interruptible
, uint64_t deadline
, turnstile_type_t type
);
835 lck_rw_sleep_with_inheritor_and_turnstile_type(lck_rw_t
*lock
, lck_sleep_action_t lck_sleep_action
, event_t event
, thread_t inheritor
, wait_interrupt_t interruptible
, uint64_t deadline
, turnstile_type_t type
);
838 wakeup_with_inheritor_and_turnstile_type(event_t event
, turnstile_type_t type
, wait_result_t result
, bool wake_one
, lck_wake_action_t action
, thread_t
*thread_wokenup
);
841 change_sleep_inheritor_and_turnstile_type(event_t event
, thread_t inheritor
, turnstile_type_t type
);
843 #endif /* KERNEL_PRIVATE */
844 #if XNU_KERNEL_PRIVATE
848 /* pthread_workqueue.c */
849 extern void workq_reference(struct workqueue
*wq
);
850 extern void workq_deallocate_safe(struct workqueue
*wq
);
851 extern bool workq_is_current_thread_updating_turnstile(struct workqueue
*wq
);
852 extern void workq_schedule_creator_turnstile_redrive(struct workqueue
*wq
,
855 #endif /* XNU_KERNEL_PRIVATE */
857 #endif /* _TURNSTILE_H_ */