+static int nfree_msgmaps; /* # of free map entries */
+static short free_msgmaps; /* free map entries list head */
+static struct msg *free_msghdrs; /* list of free msg headers */
+char *msgpool; /* MSGMAX byte long msg buffer pool */
+struct msgmap *msgmaps; /* MSGSEG msgmap structures */
+struct msg *msghdrs; /* MSGTQL msg headers */
+struct user_msqid_ds *msqids; /* MSGMNI user_msqid_ds struct's */
+
+static lck_grp_t *sysv_msg_subsys_lck_grp;
+static lck_grp_attr_t *sysv_msg_subsys_lck_grp_attr;
+static lck_attr_t *sysv_msg_subsys_lck_attr;
+static lck_mtx_t sysv_msg_subsys_mutex;
+
+#define SYSV_MSG_SUBSYS_LOCK() lck_mtx_lock(&sysv_msg_subsys_mutex)
+#define SYSV_MSG_SUBSYS_UNLOCK() lck_mtx_unlock(&sysv_msg_subsys_mutex)
+
+void sysv_msg_lock_init(void);
+
+
+#ifdef __APPLE_API_PRIVATE
+struct msginfo msginfo = {
+ MSGMAX, /* = (MSGSSZ*MSGSEG) : max chars in a message */
+ MSGMNI, /* = 40 : max message queue identifiers */
+ MSGMNB, /* = 2048 : max chars in a queue */
+ MSGTQL, /* = 40 : max messages in system */
+ MSGSSZ, /* = 8 : size of a message segment (2^N long) */
+ MSGSEG /* = 2048 : number of message segments */
+};
+#endif /* __APPLE_API_PRIVATE */
+
+/* Initialize the mutex governing access to the SysV msg subsystem */
+__private_extern__ void
+sysv_msg_lock_init( void )
+{
+ sysv_msg_subsys_lck_grp_attr = lck_grp_attr_alloc_init();
+ lck_grp_attr_setstat(sysv_msg_subsys_lck_grp_attr);
+
+ sysv_msg_subsys_lck_grp = lck_grp_alloc_init("sysv_msg_subsys_lock", sysv_msg_subsys_lck_grp_attr);
+
+ sysv_msg_subsys_lck_attr = lck_attr_alloc_init();
+ /* lck_attr_setdebug(sysv_msg_subsys_lck_attr); */
+ lck_mtx_init(&sysv_msg_subsys_mutex, sysv_msg_subsys_lck_grp, sysv_msg_subsys_lck_attr);
+}
+
+static __inline__ user_time_t
+sysv_msgtime(void)
+{
+ struct timeval tv;
+ microtime(&tv);
+ return (tv.tv_sec);
+}
+
+/*
+ * NOTE: Source and target may *NOT* overlap! (target is smaller)
+ */
+static void
+msqid_ds_64to32(struct user_msqid_ds *in, struct msqid_ds *out)
+{
+ out->msg_perm = in->msg_perm;
+ out->msg_qnum = in->msg_qnum;
+ out->msg_cbytes = in->msg_cbytes; /* for ipcs */
+ out->msg_qbytes = in->msg_qbytes;
+ out->msg_lspid = in->msg_lspid;
+ out->msg_lrpid = in->msg_lrpid;
+ out->msg_stime = in->msg_stime; /* XXX loss of range */
+ out->msg_rtime = in->msg_rtime; /* XXX loss of range */
+ out->msg_ctime = in->msg_ctime; /* XXX loss of range */
+}
+
+/*
+ * NOTE: Source and target may are permitted to overlap! (source is smaller);
+ * this works because we copy fields in order from the end of the struct to
+ * the beginning.
+ */
+static void
+msqid_ds_32to64(struct msqid_ds *in, struct user_msqid_ds *out)
+{
+ out->msg_ctime = in->msg_ctime;
+ out->msg_rtime = in->msg_rtime;
+ out->msg_stime = in->msg_stime;
+ out->msg_lrpid = in->msg_lrpid;
+ out->msg_lspid = in->msg_lspid;
+ out->msg_qbytes = in->msg_qbytes;
+ out->msg_cbytes = in->msg_cbytes; /* for ipcs */
+ out->msg_qnum = in->msg_qnum;
+ out->msg_perm = in->msg_perm;
+}
+
+/* This routine assumes the system is locked prior to calling this routine */
+void
+msginit(__unused void *dummy)