xref: /dragonfly/lib/libc/sysvipc/sysvipc_msg.h (revision ff86f401)
182657471SMarkus Pfeiffer /* $FreeBSD: src/sys/kern/sysv_msg.c,v 1.23.2.5 2002/12/31 08:54:53 maxim Exp $ */
282657471SMarkus Pfeiffer 
382657471SMarkus Pfeiffer /*
482657471SMarkus Pfeiffer  * Implementation of SVID messages
582657471SMarkus Pfeiffer  *
682657471SMarkus Pfeiffer  * Author:  Daniel Boulet
782657471SMarkus Pfeiffer  *
882657471SMarkus Pfeiffer  * Copyright 1993 Daniel Boulet and RTMX Inc.
982657471SMarkus Pfeiffer  * Copyright (c) 2013 Larisa Grigore <larisagrigore@gmail.com>
1082657471SMarkus Pfeiffer  *
1182657471SMarkus Pfeiffer  * This system call was implemented by Daniel Boulet under contract from RTMX.
1282657471SMarkus Pfeiffer  *
1382657471SMarkus Pfeiffer  * Redistribution and use in source forms, with and without modification,
1482657471SMarkus Pfeiffer  * are permitted provided that this entire comment appears intact.
1582657471SMarkus Pfeiffer  *
1682657471SMarkus Pfeiffer  * Redistribution in binary form may occur without any restrictions.
1782657471SMarkus Pfeiffer  * Obviously, it would be nice if you gave credit where credit is due
1882657471SMarkus Pfeiffer  * but requiring it would be too onerous.
1982657471SMarkus Pfeiffer  *
2082657471SMarkus Pfeiffer  * This software is provided ``AS IS'' without any warranties of any kind.
2182657471SMarkus Pfeiffer  */
2282657471SMarkus Pfeiffer 
23*ff86f401SSascha Wildner #ifndef _SYSVIPC_MSG_H_
24*ff86f401SSascha Wildner #define _SYSVIPC_MSG_H_
2582657471SMarkus Pfeiffer 
2682657471SMarkus Pfeiffer #include <sys/msg.h>
2782657471SMarkus Pfeiffer #include "sysvipc_lock.h"
2882657471SMarkus Pfeiffer #include "sysvipc_lock_generic.h"
2982657471SMarkus Pfeiffer 
3082657471SMarkus Pfeiffer struct msg {
3182657471SMarkus Pfeiffer 	short	msg_next;	/* next msg in the chain */
3282657471SMarkus Pfeiffer 	long	msg_type;	/* type of this message */
3382657471SMarkus Pfeiffer     				/* >0 -> type of this message */
3482657471SMarkus Pfeiffer     				/* 0 -> free header */
3582657471SMarkus Pfeiffer 	u_short	msg_ts;		/* size of this message */
3682657471SMarkus Pfeiffer 	short	msg_spot;	/* location of start of msg in buffer */
3782657471SMarkus Pfeiffer };
3882657471SMarkus Pfeiffer 
3982657471SMarkus Pfeiffer /* Intarnal structure defined to keep compatbility with
4082657471SMarkus Pfeiffer  * th kernel implementation.
4182657471SMarkus Pfeiffer  */
4282657471SMarkus Pfeiffer struct msqid_ds_internal {
4382657471SMarkus Pfeiffer 	struct	ipc_perm msg_perm;	/* msg queue permission bits */
4482657471SMarkus Pfeiffer 	union {
4582657471SMarkus Pfeiffer 		struct	msg *msg_first;
4682657471SMarkus Pfeiffer 		int msg_first_index;
4782657471SMarkus Pfeiffer 	} first;
4882657471SMarkus Pfeiffer 	union {
4982657471SMarkus Pfeiffer 		struct	msg *msg_last;
5082657471SMarkus Pfeiffer 		int msg_last_index;
5182657471SMarkus Pfeiffer 	} last;
5282657471SMarkus Pfeiffer 	u_long	msg_cbytes;	/* number of bytes in use on the queue */
5382657471SMarkus Pfeiffer 	u_long	msg_qnum;	/* number of msgs in the queue */
5482657471SMarkus Pfeiffer 	u_long	msg_qbytes;	/* max # of bytes on the queue */
5582657471SMarkus Pfeiffer 	pid_t	msg_lspid;	/* pid of last msgsnd() */
5682657471SMarkus Pfeiffer 	pid_t	msg_lrpid;	/* pid of last msgrcv() */
5782657471SMarkus Pfeiffer 	time_t	msg_stime;	/* time of last msgsnd() */
5882657471SMarkus Pfeiffer 	long	msg_pad1;
5982657471SMarkus Pfeiffer 	time_t	msg_rtime;	/* time of last msgrcv() */
6082657471SMarkus Pfeiffer 	long	msg_pad2;
6182657471SMarkus Pfeiffer 	time_t	msg_ctime;	/* time of last msgctl() */
6282657471SMarkus Pfeiffer 	long	msg_pad3;
6382657471SMarkus Pfeiffer 	long	msg_pad4[4];
6482657471SMarkus Pfeiffer };
6582657471SMarkus Pfeiffer 
6682657471SMarkus Pfeiffer #ifndef MSGSSZ
6782657471SMarkus Pfeiffer #define MSGSSZ	8		/* Each segment must be 2^N long */
6882657471SMarkus Pfeiffer #endif
6982657471SMarkus Pfeiffer #ifndef MSGSEG
7082657471SMarkus Pfeiffer #define MSGSEG	256		/* must be calculated such that all
7182657471SMarkus Pfeiffer 					structure fits in PAGE_SIZE. */
7282657471SMarkus Pfeiffer #endif
7382657471SMarkus Pfeiffer #define MSGMAX	(MSGSSZ*MSGSEG)
7482657471SMarkus Pfeiffer #ifndef MSGMNB
7582657471SMarkus Pfeiffer #define MSGMNB	2048		/* max # of bytes in a queue */
7682657471SMarkus Pfeiffer #endif
7782657471SMarkus Pfeiffer #ifndef MSGMNI
7882657471SMarkus Pfeiffer #define MSGMNI	40
7982657471SMarkus Pfeiffer #endif
8082657471SMarkus Pfeiffer #ifndef MSGTQL
8182657471SMarkus Pfeiffer #define MSGTQL	10//40
8282657471SMarkus Pfeiffer #endif
8382657471SMarkus Pfeiffer 
8482657471SMarkus Pfeiffer  /* Each message is broken up and stored in segments that are msgssz bytes
8582657471SMarkus Pfeiffer  * long.  For efficiency reasons, this should be a power of two.  Also,
8682657471SMarkus Pfeiffer  * it doesn't make sense if it is less than 8 or greater than about 256.
8782657471SMarkus Pfeiffer  * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of
8882657471SMarkus Pfeiffer  * two between 8 and 1024 inclusive (and panic's if it isn't).
8982657471SMarkus Pfeiffer  */
9082657471SMarkus Pfeiffer struct msginfo {
9182657471SMarkus Pfeiffer 	int	msgmax,		/* max chars in a message */
9282657471SMarkus Pfeiffer 		msgmni,		/* max message queue identifiers */
9382657471SMarkus Pfeiffer 		msgmnb,		/* max chars in a queue */
9482657471SMarkus Pfeiffer 		msgtql,		/* max messages in system */
9582657471SMarkus Pfeiffer 		msgssz,		/* size of a message segment (see notes above) */
9682657471SMarkus Pfeiffer 		msgseg;		/* number of message segments */
9782657471SMarkus Pfeiffer };
9882657471SMarkus Pfeiffer 
9982657471SMarkus Pfeiffer struct msgmap {
10082657471SMarkus Pfeiffer 	short	next;		/* next segment in buffer */
10182657471SMarkus Pfeiffer     				/* -1 -> available */
10282657471SMarkus Pfeiffer     				/* 0..(MSGSEG-1) -> index of next segment */
10382657471SMarkus Pfeiffer };
10482657471SMarkus Pfeiffer 
10582657471SMarkus Pfeiffer struct msqid_pool {
10682657471SMarkus Pfeiffer #ifdef SYSV_RWLOCK
10782657471SMarkus Pfeiffer 	struct sysv_rwlock rwlock;
10882657471SMarkus Pfeiffer #else
10982657471SMarkus Pfeiffer 	struct sysv_mutex mutex;
11082657471SMarkus Pfeiffer #endif
11182657471SMarkus Pfeiffer 	struct msqid_ds_internal ds;
11282657471SMarkus Pfeiffer 	char gen;
11382657471SMarkus Pfeiffer 	int nfree_msgmaps;	/* # of free map entries */
11482657471SMarkus Pfeiffer 	short free_msgmaps;	/* head of linked list of free map entries */
11582657471SMarkus Pfeiffer 	short free_msghdrs;/* list of free msg headers */
11682657471SMarkus Pfeiffer 	struct msg msghdrs[MSGTQL];	/* MSGTQL msg headers */
11782657471SMarkus Pfeiffer 	struct msgmap msgmaps[MSGSEG];	/* MSGSEG msgmap structures */
11882657471SMarkus Pfeiffer 	char msgpool[MSGMAX];		/* MSGMAX byte long msg buffer pool */
11982657471SMarkus Pfeiffer };
12082657471SMarkus Pfeiffer 
12182657471SMarkus Pfeiffer int sysvipc_msgctl(int, int, struct msqid_ds *);
12282657471SMarkus Pfeiffer int sysvipc_msgget(key_t, int);
123d217426cSSascha Wildner int sysvipc_msgsnd(int, const void *, size_t, int);
12482657471SMarkus Pfeiffer int sysvipc_msgrcv(int, void *, size_t, long, int);
12582657471SMarkus Pfeiffer 
126*ff86f401SSascha Wildner #endif /* !_SYSVIPC_MSG_H_ */
127