+kern_return_t
+wait_queue_sub_clearrefs(
+ wait_queue_set_t wq_set)
+{
+ if (!wait_queue_is_set(wq_set))
+ return KERN_INVALID_ARGUMENT;
+
+ wqs_lock(wq_set);
+ wq_set->wqs_refcount = 0;
+ wqs_unlock(wq_set);
+ return KERN_SUCCESS;
+}
+
+/*
+ *
+ * Routine: wait_queue_set_size
+ * Routine: wait_queue_link_size
+ * Purpose:
+ * Return the size of opaque wait queue structures
+ */
+unsigned int wait_queue_set_size(void) { return sizeof(WaitQueueSet); }
+unsigned int wait_queue_link_size(void) { return sizeof(WaitQueueLink); }
+
+/* declare a unique type for wait queue link structures */
+static unsigned int _wait_queue_link;
+static unsigned int _wait_queue_unlinked;
+
+#define WAIT_QUEUE_LINK ((void *)&_wait_queue_link)
+#define WAIT_QUEUE_UNLINKED ((void *)&_wait_queue_unlinked)
+
+#define WAIT_QUEUE_ELEMENT_CHECK(wq, wqe) \
+ WQASSERT(((wqe)->wqe_queue == (wq) && \
+ queue_next(queue_prev((queue_t) (wqe))) == (queue_t)(wqe)), \
+ "wait queue element list corruption: wq=%#x, wqe=%#x", \
+ (wq), (wqe))
+
+#define WQSPREV(wqs, wql) ((wait_queue_link_t)queue_prev( \
+ ((&(wqs)->wqs_setlinks == (queue_t)(wql)) ? \
+ (queue_t)(wql) : &(wql)->wql_setlinks)))
+
+#define WQSNEXT(wqs, wql) ((wait_queue_link_t)queue_next( \
+ ((&(wqs)->wqs_setlinks == (queue_t)(wql)) ? \
+ (queue_t)(wql) : &(wql)->wql_setlinks)))
+
+#define WAIT_QUEUE_SET_LINK_CHECK(wqs, wql) \
+ WQASSERT((((wql)->wql_type == WAIT_QUEUE_LINK) && \
+ ((wql)->wql_setqueue == (wqs)) && \
+ ((wql)->wql_queue->wq_type == _WAIT_QUEUE_inited) && \
+ (WQSNEXT((wqs), WQSPREV((wqs),(wql))) == (wql))), \
+ "wait queue set links corruption: wqs=%#x, wql=%#x", \
+ (wqs), (wql))
+
+#if defined(_WAIT_QUEUE_DEBUG_)
+
+#define WQASSERT(e, s, p0, p1) ((e) ? 0 : panic(s, p0, p1))
+
+#define WAIT_QUEUE_CHECK(wq) \
+MACRO_BEGIN \
+ queue_t q2 = &(wq)->wq_queue; \
+ wait_queue_element_t wqe2 = (wait_queue_element_t) queue_first(q2); \
+ while (!queue_end(q2, (queue_entry_t)wqe2)) { \
+ WAIT_QUEUE_ELEMENT_CHECK((wq), wqe2); \
+ wqe2 = (wait_queue_element_t) queue_next((queue_t) wqe2); \
+ } \
+MACRO_END
+
+#define WAIT_QUEUE_SET_CHECK(wqs) \
+MACRO_BEGIN \
+ queue_t q2 = &(wqs)->wqs_setlinks; \
+ wait_queue_link_t wql2 = (wait_queue_link_t) queue_first(q2); \
+ while (!queue_end(q2, (queue_entry_t)wql2)) { \
+ WAIT_QUEUE_SET_LINK_CHECK((wqs), wql2); \
+ wql2 = (wait_queue_link_t) wql2->wql_setlinks.next; \
+ } \
+MACRO_END
+
+#else /* !_WAIT_QUEUE_DEBUG_ */
+
+#define WQASSERT(e, s, p0, p1) assert(e)
+
+#define WAIT_QUEUE_CHECK(wq)
+#define WAIT_QUEUE_SET_CHECK(wqs)
+
+#endif /* !_WAIT_QUEUE_DEBUG_ */