#include <kern/macro_help.h>
#include <kern/kern_types.h>
#include <kern/spl.h>
-#include <kern/wait_queue.h>
+#include <kern/waitq.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_object.h>
typedef struct ipc_mqueue {
union {
struct {
- struct wait_queue wait_queue;
+ struct waitq waitq;
struct ipc_kmsg_queue messages;
- mach_port_msgcount_t msgcount;
- mach_port_msgcount_t qlimit;
mach_port_seqno_t seqno;
mach_port_name_t receiver_name;
- boolean_t fullwaiters;
- } port;
+ uint16_t msgcount;
+ uint16_t qlimit;
+ } __attribute__((__packed__)) port;
struct {
- struct wait_queue_set set_queue;
+ struct waitq_set setq;
mach_port_name_t local_name;
- } pset;
+ } __attribute__((__packed__)) pset;
} data;
} *ipc_mqueue_t;
#define IMQ_NULL ((ipc_mqueue_t) 0)
-#define imq_wait_queue data.port.wait_queue
+#define imq_wait_queue data.port.waitq
#define imq_messages data.port.messages
#define imq_msgcount data.port.msgcount
#define imq_qlimit data.port.qlimit
#define imq_seqno data.port.seqno
#define imq_receiver_name data.port.receiver_name
-#define imq_fullwaiters data.port.fullwaiters
-#define imq_set_queue data.pset.set_queue
-#define imq_setlinks data.pset.set_queue.wqs_setlinks
-#define imq_preposts data.pset.set_queue.wqs_preposts
+/*
+ * 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_set_queue data.pset.setq
#define imq_local_name data.pset.local_name
-#define imq_is_set(mq) wait_queue_is_set(&(mq)->imq_set_queue)
+#define imq_is_set(mq) waitqs_is_set(&(mq)->imq_set_queue)
+
+#define imq_lock(mq) waitq_lock(&(mq)->imq_wait_queue)
+#define imq_lock_try(mq) waitq_lock_try(&(mq)->imq_wait_queue)
+#define imq_unlock(mq) waitq_unlock(&(mq)->imq_wait_queue)
+#define imq_held(mq) waitq_held(&(mq)->imq_wait_queue)
+
+extern void imq_reserve_and_lock(ipc_mqueue_t mq,
+ uint64_t *reserved_prepost, spl_t *spl);
-#define imq_lock(mq) wait_queue_lock(&(mq)->imq_wait_queue)
-#define imq_lock_try(mq) wait_queue_lock_try(&(mq)->imq_wait_queue)
-#define imq_unlock(mq) wait_queue_unlock(&(mq)->imq_wait_queue)
-#define imq_held(mq) wait_queue_held(&(mq)->imq_wait_queue)
+extern void imq_release_and_unlock(ipc_mqueue_t mq,
+ uint64_t reserved_prepost, spl_t spl);
#define imq_full(mq) ((mq)->imq_msgcount >= (mq)->imq_qlimit)
#define imq_full_kernel(mq) ((mq)->imq_msgcount >= MACH_PORT_QLIMIT_KERNEL)
/* Initialize a newly-allocated message queue */
extern void ipc_mqueue_init(
ipc_mqueue_t mqueue,
- boolean_t is_set);
+ boolean_t is_set,
+ uint64_t *reserved_link);
+
+/* de-initialize / cleanup an mqueue (specifically waitq resources) */
+extern void ipc_mqueue_deinit(
+ ipc_mqueue_t mqueue);
/* destroy an mqueue */
extern void ipc_mqueue_destroy(
/* Add the specific mqueue as a member of the set */
extern kern_return_t ipc_mqueue_add(
ipc_mqueue_t mqueue,
- ipc_mqueue_t set_mqueue);
+ ipc_mqueue_t set_mqueue,
+ uint64_t *reserved_link,
+ uint64_t *reserved_prepost);
/* Check to see if mqueue is member of set_mqueue */
extern boolean_t ipc_mqueue_member(
mach_msg_timeout_t timeout_val,
spl_t s);
+/* check for queue send queue full of a port */
+extern mach_msg_return_t ipc_mqueue_preflight_send(
+ ipc_mqueue_t mqueue,
+ ipc_kmsg_t kmsg,
+ mach_msg_option_t option,
+ mach_msg_timeout_t timeout_val);
+
/* Deliver message to message queue or waiting receiver */
extern void ipc_mqueue_post(
ipc_mqueue_t mqueue,
/* Select a message from a queue and try to post it to ourself */
extern void ipc_mqueue_select_on_thread(
- ipc_mqueue_t mqueue,
+ ipc_mqueue_t port_mq,
+ ipc_mqueue_t set_mq,
mach_msg_option_t option,
mach_msg_size_t max_size,
thread_t thread);
/* Peek into a messaqe queue to see if there are messages */
-extern int ipc_mqueue_peek(
+extern unsigned ipc_mqueue_peek(
+ ipc_mqueue_t mqueue,
+ mach_port_seqno_t *msg_seqnop,
+ mach_msg_size_t *msg_sizep,
+ mach_msg_id_t *msg_idp,
+ mach_msg_max_trailer_t *msg_trailerp);
+
+/* Peek into a messaqe queue set to see if there are queues with messages */
+extern unsigned ipc_mqueue_set_peek(
ipc_mqueue_t mqueue);
+/* Gather the names of member port for a given set */
+extern void ipc_mqueue_set_gather_member_names(
+ ipc_space_t space,
+ ipc_mqueue_t set_mq,
+ ipc_entry_num_t maxnames,
+ mach_port_name_t *names,
+ ipc_entry_num_t *actualp);
+
/* Clear a message count reservation */
extern void ipc_mqueue_release_msgcount(
- ipc_mqueue_t mqueue);
+ ipc_mqueue_t port_mq,
+ ipc_mqueue_t set_mq);
/* Change a queue limit */
extern void ipc_mqueue_set_qlimit(