#include <mach/kern_return.h> /* for kern_return_t */
#include <kern/kern_types.h> /* for wait_queue_t */
+#include <kern/queue.h>
#include <sys/cdefs.h>
#ifdef MACH_KERNEL_PRIVATE
#include <kern/lock.h>
-#include <kern/queue.h>
+#include <mach/branch_predicates.h>
#include <machine/cpu_number.h>
#include <machine/machine_routines.h> /* machine_timeout_suspended() */
#define wait_queue_lock_try(wq) (hw_lock_try(&(wq)->wq_interlock))
/* For x86, the hardware timeout is in TSC units. */
-#if defined(i386)
+#if defined(i386) || defined(x86_64)
#define hwLockTimeOut LockTimeOutTSC
#else
#define hwLockTimeOut LockTimeOut
*/
static inline void wait_queue_lock(wait_queue_t wq) {
- if (hw_lock_to(&(wq)->wq_interlock, hwLockTimeOut * 2) == 0) {
+ if (__improbable(hw_lock_to(&(wq)->wq_interlock, hwLockTimeOut * 2) == 0)) {
boolean_t wql_acquired = FALSE;
+
while (machine_timeout_suspended()) {
#if defined(__i386__) || defined(__x86_64__)
/*
if ((wql_acquired = hw_lock_to(&(wq)->wq_interlock, hwLockTimeOut * 2)))
break;
}
-
if (wql_acquired == FALSE)
panic("wait queue deadlock - wq=%p, cpu=%d\n", wq, cpu_number());
}
hash ^= (hash >> 11);
hash += (hash << 15);
+ hash &= (num_wait_queues - 1);
return hash;
}
-/* TBD: It should be possible to eliminate the divide here */
-#define wait_hash(event) \
- (wq_hash((char *)&event) % (num_wait_queues))
+#define wait_hash(event) wq_hash((char *)&event)
#endif /* MACH_KERNEL_PRIVATE */
extern kern_return_t wait_queue_set_unlink_all(
wait_queue_set_t set_queue);
+#ifdef XNU_KERNEL_PRIVATE
+extern kern_return_t wait_queue_set_unlink_one(
+ wait_queue_set_t set_queue,
+ wait_queue_link_t link);
+
+extern kern_return_t wait_queue_unlink_nofree(
+ wait_queue_t wait_queue,
+ wait_queue_set_t set_queue,
+ wait_queue_link_t *wqlp);
+
+extern kern_return_t wait_queue_unlink_all_nofree(
+ wait_queue_t wait_queue,
+ queue_t links);
+
+extern kern_return_t wait_queue_set_unlink_all_nofree(
+ wait_queue_set_t set_queue,
+ queue_t links);
+
+extern wait_queue_link_t wait_queue_link_allocate(void);
+
+#endif /* XNU_KERNEL_PRIVATE */
+
/* legacy API */
kern_return_t wait_queue_sub_init(
wait_queue_set_t set_queue,
extern kern_return_t wait_queue_wakeup_one(
wait_queue_t wait_queue,
event_t wake_event,
- wait_result_t result);
+ wait_result_t result,
+ int priority);
/* wakeup all the threads waiting on <wait_queue,event> pair */
extern kern_return_t wait_queue_wakeup_all(