+/*
+ * we can use the 'eventmask' bits of the waitq b/c
+ * they are only used by global queues
+ */
+#define imq_fullwaiters data.port.waitq.waitq_eventmask
+#define imq_in_pset data.port.waitq.waitq_set_id
+#define imq_preposts data.port.waitq.waitq_prepost_id
+
+#define imq_set_queue data.pset.setq
+#define imq_is_set(mq) waitqs_is_set(&(mq)->imq_set_queue)
+#define imq_is_queue(mq) waitq_is_queue(&(mq)->imq_wait_queue)
+#define imq_is_turnstile_proxy(mq) \
+ waitq_is_turnstile_proxy(&(mq)->imq_wait_queue)
+#define imq_is_valid(mq) waitq_is_valid(&(mq)->imq_wait_queue)
+
+#define imq_unlock(mq) waitq_unlock(&(mq)->imq_wait_queue)
+#define imq_held(mq) waitq_held(&(mq)->imq_wait_queue)
+#define imq_valid(mq) waitq_valid(&(mq)->imq_wait_queue)
+
+extern void imq_lock(ipc_mqueue_t mq);
+extern unsigned int imq_lock_try(ipc_mqueue_t mq);
+
+/*
+ * Get an ipc_mqueue pointer from a waitq pointer. These are traditionally the
+ * same pointer, but this conversion makes no assumptions on union structure
+ * member positions - it should allow the waitq to move around in either the
+ * port-set mqueue or the port mqueue independently.
+ */
+#define imq_from_waitq(waitq) (waitq_is_set(waitq) ? \
+ __container_of(waitq, struct ipc_mqueue, imq_set_queue.wqset_q) : \
+ __container_of(waitq, struct ipc_mqueue, imq_wait_queue))
+
+#define imq_to_object(mq) ip_to_object(ip_from_mq(mq))
+
+extern void imq_reserve_and_lock(ipc_mqueue_t mq,
+ uint64_t *reserved_prepost);
+
+extern void imq_release_and_unlock(ipc_mqueue_t mq,
+ uint64_t reserved_prepost);