10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52565Sudpa  * Common Development and Distribution License (the "License").
62565Sudpa  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*4153Sdv142724  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	_SYS_MSG_IMPL_H
270Sstevel@tonic-gate #define	_SYS_MSG_IMPL_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <sys/ipc_impl.h>
320Sstevel@tonic-gate #if defined(_KERNEL) || defined(_KMEMUSER)
330Sstevel@tonic-gate #include <sys/msg.h>
340Sstevel@tonic-gate #include <sys/t_lock.h>
350Sstevel@tonic-gate #include <sys/list.h>
360Sstevel@tonic-gate #endif
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #ifdef	__cplusplus
390Sstevel@tonic-gate extern "C" {
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * Argument vectors for the various flavors of msgsys().
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #define	MSGGET	0
470Sstevel@tonic-gate #define	MSGCTL	1
480Sstevel@tonic-gate #define	MSGRCV	2
490Sstevel@tonic-gate #define	MSGSND	3
500Sstevel@tonic-gate #define	MSGIDS	4
510Sstevel@tonic-gate #define	MSGSNAP	5
520Sstevel@tonic-gate 
530Sstevel@tonic-gate #if defined(_KERNEL) || defined(_KMEMUSER)
540Sstevel@tonic-gate 
55*4153Sdv142724 typedef struct  msgq_wakeup {
56*4153Sdv142724 	list_node_t	msgw_list;
57*4153Sdv142724 	long		msgw_type;	/* Message type request. */
58*4153Sdv142724 	long		msgw_snd_wake;	/* Type of msg from msgsnd */
59*4153Sdv142724 	kthread_t	*msgw_thrd;	/* Thread waiting */
60*4153Sdv142724 	kcondvar_t	msgw_wake_cv;	/* waiting on this */
61*4153Sdv142724 } msgq_wakeup_t;
62*4153Sdv142724 
63*4153Sdv142724 
64*4153Sdv142724 typedef struct msg_select {
65*4153Sdv142724 	msgq_wakeup_t *(*selection)();
66*4153Sdv142724 	struct msg_select *next_selection;
67*4153Sdv142724 } msg_select_t;
68*4153Sdv142724 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  * There is one msg structure for each message in the system.
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate struct msg {
730Sstevel@tonic-gate 	list_node_t	msg_node;	/* message list node */
740Sstevel@tonic-gate 	long		msg_type;	/* message type */
750Sstevel@tonic-gate 	size_t		msg_size;	/* message text size */
760Sstevel@tonic-gate 	void		*msg_addr;	/* message text address */
770Sstevel@tonic-gate 	long		msg_flags;	/* message flags */
780Sstevel@tonic-gate 	long		msg_copycnt;	/* current # of copyouts on message */
790Sstevel@tonic-gate };
800Sstevel@tonic-gate 
810Sstevel@tonic-gate /*
820Sstevel@tonic-gate  * Per message flags
830Sstevel@tonic-gate  */
840Sstevel@tonic-gate #define	MSG_RCVCOPY	00001	/* msgrcv is copying out this message */
850Sstevel@tonic-gate #define	MSG_UNLINKED	00002	/* msg has been unlinked from queue */
860Sstevel@tonic-gate 
872565Sudpa /*
882565Sudpa  * msg_rcv_cv is now an array of kcondvar_t for performance reason.
892565Sudpa  * We use multiple condition variables (kcondvar_t) to avoid needing
902565Sudpa  * to wake all readers when sending a single message.
912565Sudpa  */
92*4153Sdv142724 
93*4153Sdv142724 #define	MSG_NEG_INTERVAL 8
94*4153Sdv142724 #define	MSG_MAX_QNUM	64
95*4153Sdv142724 #define	MSG_MAX_QNUM_CV	65
962565Sudpa 
970Sstevel@tonic-gate typedef struct kmsqid {
980Sstevel@tonic-gate 	kipc_perm_t	msg_perm;	/* operation permission struct */
990Sstevel@tonic-gate 	list_t		msg_list;	/* list of messages on q */
1000Sstevel@tonic-gate 	msglen_t	msg_cbytes;	/* current # bytes on q */
1010Sstevel@tonic-gate 	msgqnum_t	msg_qnum;	/* # of messages on q */
1020Sstevel@tonic-gate 	msgqnum_t	msg_qmax;	/* max # of messages on q */
1030Sstevel@tonic-gate 	msglen_t	msg_qbytes;	/* max # of bytes on q */
1040Sstevel@tonic-gate 	pid_t		msg_lspid;	/* pid of last msgsnd */
1050Sstevel@tonic-gate 	pid_t		msg_lrpid;	/* pid of last msgrcv */
1060Sstevel@tonic-gate 	time_t		msg_stime;	/* last msgsnd time */
1070Sstevel@tonic-gate 	time_t		msg_rtime;	/* last msgrcv time */
1080Sstevel@tonic-gate 	time_t		msg_ctime;	/* last change time */
109*4153Sdv142724 	uint_t		msg_snd_cnt;	/* # of waiting senders */
110*4153Sdv142724 	uint_t		msg_rcv_cnt;	/* # of waiting receivers */
111*4153Sdv142724 	uint64_t	msg_lowest_type; /* Smallest type on queue */
112*4153Sdv142724 	/*
113*4153Sdv142724 	 * linked list of routines used to determine what to wake up next.
114*4153Sdv142724 	 * 	msg_fnd_sndr:	Routines for waking up readers waiting
115*4153Sdv142724 	 *			for a message from the sender.
116*4153Sdv142724 	 *	msg_fnd_rdr:	Routines for waking up readers waiting
117*4153Sdv142724 	 *			for a copyout to finish.
118*4153Sdv142724 	 */
119*4153Sdv142724 	msg_select_t	*msg_fnd_sndr;
120*4153Sdv142724 	msg_select_t	*msg_fnd_rdr;
121*4153Sdv142724 	/*
122*4153Sdv142724 	 * Various counts and queues for controlling the sleeping
123*4153Sdv142724 	 * and waking up of processes that are waiting for various
124*4153Sdv142724 	 * message queue events.
125*4153Sdv142724 	 *
126*4153Sdv142724 	 * msg_cpy_block:   List of receiving threads that are blocked because
127*4153Sdv142724 	 *		    the message of choice is being copied out.
128*4153Sdv142724 	 * msg_wait_snd:    List of receiving threads whose type specifier
129*4153Sdv142724 	 *		    is positive or 0 but are blocked because there
130*4153Sdv142724 	 *		    are no matches.
131*4153Sdv142724 	 * msg_wait_snd_ngt:
132*4153Sdv142724 	 *		    List of receiving threads whose type specifier is
133*4153Sdv142724 	 *		    negative message type but are blocked because
134*4153Sdv142724 	 *		    there are no types that qualify.
135*4153Sdv142724 	 */
1360Sstevel@tonic-gate 	kcondvar_t	msg_snd_cv;
137*4153Sdv142724 	list_t		msg_cpy_block;
138*4153Sdv142724 	list_t		msg_wait_snd[MSG_MAX_QNUM_CV];
139*4153Sdv142724 	list_t		msg_wait_snd_ngt[MSG_MAX_QNUM_CV];
140*4153Sdv142724 	int		msg_ngt_cnt;	/* # of negative receivers blocked */
141*4153Sdv142724 	char		msg_neg_copy;	/* Neg type copy underway */
1420Sstevel@tonic-gate } kmsqid_t;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #endif	/* _KERNEL */
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate #if defined(_SYSCALL32)
1470Sstevel@tonic-gate /*
1480Sstevel@tonic-gate  * LP64 view of the ILP32 msgbuf structure
1490Sstevel@tonic-gate  */
1500Sstevel@tonic-gate struct ipcmsgbuf32 {
1510Sstevel@tonic-gate 	int32_t	mtype;		/* message type */
1520Sstevel@tonic-gate 	char	mtext[1];	/* message text */
1530Sstevel@tonic-gate };
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate /*
1560Sstevel@tonic-gate  * LP64 view of the ILP32 msgsnap_head and msgsnap_mhead structures
1570Sstevel@tonic-gate  */
1580Sstevel@tonic-gate struct msgsnap_head32 {
1590Sstevel@tonic-gate 	size32_t msgsnap_size;	/* bytes consumed/required in the buffer */
1600Sstevel@tonic-gate 	size32_t msgsnap_nmsg;	/* number of messages in the buffer */
1610Sstevel@tonic-gate };
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate struct msgsnap_mhead32 {
1640Sstevel@tonic-gate 	size32_t msgsnap_mlen;	/* number of bytes in message that follows */
1650Sstevel@tonic-gate 	int32_t	msgsnap_mtype;	/* message type */
1660Sstevel@tonic-gate };
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate  * LP64 view of the ILP32 msqid_ds structure
1700Sstevel@tonic-gate  */
1710Sstevel@tonic-gate struct msqid_ds32 {
1720Sstevel@tonic-gate 	struct ipc_perm32 msg_perm;	/* operation permission struct */
1730Sstevel@tonic-gate 	caddr32_t	msg_first;	/* ptr to first message on q */
1740Sstevel@tonic-gate 	caddr32_t	msg_last;	/* ptr to last message on q */
1750Sstevel@tonic-gate 	uint32_t	msg_cbytes;	/* current # bytes on q */
1760Sstevel@tonic-gate 	uint32_t	msg_qnum;	/* # of messages on q */
1770Sstevel@tonic-gate 	uint32_t	msg_qbytes;	/* max # of bytes on q */
1780Sstevel@tonic-gate 	pid32_t		msg_lspid;	/* pid of last msgsnd */
1790Sstevel@tonic-gate 	pid32_t		msg_lrpid;	/* pid of last msgrcv */
1800Sstevel@tonic-gate 	time32_t	msg_stime;	/* last msgsnd time */
1810Sstevel@tonic-gate 	int32_t		msg_pad1;	/* reserved for time_t expansion */
1820Sstevel@tonic-gate 	time32_t	msg_rtime;	/* last msgrcv time */
1830Sstevel@tonic-gate 	int32_t		msg_pad2;	/* time_t expansion */
1840Sstevel@tonic-gate 	time32_t	msg_ctime;	/* last change time */
1850Sstevel@tonic-gate 	int32_t		msg_pad3;	/* time expansion */
1860Sstevel@tonic-gate 	int16_t		msg_cv;
1870Sstevel@tonic-gate 	int16_t		msg_qnum_cv;
1880Sstevel@tonic-gate 	int32_t		msg_pad4[3];	/* reserve area */
1890Sstevel@tonic-gate };
1900Sstevel@tonic-gate #endif	/* _SYSCALL32 */
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate #ifdef	__cplusplus
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate #endif
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate #endif	/* _SYS_MSG_IMPL_H */
197