xref: /dragonfly/lib/libc/sysvipc/sysvipc_msg.h (revision de78d61c)
1 /* $FreeBSD: src/sys/kern/sysv_msg.c,v 1.23.2.5 2002/12/31 08:54:53 maxim Exp $ */
2 
3 /*
4  * Implementation of SVID messages
5  *
6  * Author:  Daniel Boulet
7  *
8  * Copyright 1993 Daniel Boulet and RTMX Inc.
9  * Copyright (c) 2013 Larisa Grigore <larisagrigore@gmail.com>
10  *
11  * This system call was implemented by Daniel Boulet under contract from RTMX.
12  *
13  * Redistribution and use in source forms, with and without modification,
14  * are permitted provided that this entire comment appears intact.
15  *
16  * Redistribution in binary form may occur without any restrictions.
17  * Obviously, it would be nice if you gave credit where credit is due
18  * but requiring it would be too onerous.
19  *
20  * This software is provided ``AS IS'' without any warranties of any kind.
21  */
22 
23 #ifndef _SYSVIPC_MSG_H_
24 #define _SYSVIPC_MSG_H_
25 
26 #include <sys/msg.h>
27 #include "sysvipc_lock.h"
28 #include "sysvipc_lock_generic.h"
29 
30 struct msg {
31 	short	msg_next;	/* next msg in the chain */
32 	long	msg_type;	/* type of this message */
33     				/* >0 -> type of this message */
34     				/* 0 -> free header */
35 	u_short	msg_ts;		/* size of this message */
36 	short	msg_spot;	/* location of start of msg in buffer */
37 };
38 
39 /* Intarnal structure defined to keep compatbility with
40  * th kernel implementation.
41  */
42 struct msqid_ds_internal {
43 	struct	ipc_perm msg_perm;	/* msg queue permission bits */
44 	union {
45 		struct	msg *msg_first;
46 		int msg_first_index;
47 	} first;
48 	union {
49 		struct	msg *msg_last;
50 		int msg_last_index;
51 	} last;
52 	u_long	msg_cbytes;	/* number of bytes in use on the queue */
53 	u_long	msg_qnum;	/* number of msgs in the queue */
54 	u_long	msg_qbytes;	/* max # of bytes on the queue */
55 	pid_t	msg_lspid;	/* pid of last msgsnd() */
56 	pid_t	msg_lrpid;	/* pid of last msgrcv() */
57 	time_t	msg_stime;	/* time of last msgsnd() */
58 	long	msg_pad1;
59 	time_t	msg_rtime;	/* time of last msgrcv() */
60 	long	msg_pad2;
61 	time_t	msg_ctime;	/* time of last msgctl() */
62 	long	msg_pad3;
63 	long	msg_pad4[4];
64 };
65 
66 #ifndef MSGSSZ
67 #define MSGSSZ	8		/* Each segment must be 2^N long */
68 #endif
69 #ifndef MSGSEG
70 #define MSGSEG	256		/* must be calculated such that all
71 					structure fits in PAGE_SIZE. */
72 #endif
73 #define MSGMAX	(MSGSSZ*MSGSEG)
74 #ifndef MSGMNB
75 #define MSGMNB	2048		/* max # of bytes in a queue */
76 #endif
77 #ifndef MSGMNI
78 #define MSGMNI	40
79 #endif
80 #ifndef MSGTQL
81 #define MSGTQL	10//40
82 #endif
83 
84  /* Each message is broken up and stored in segments that are msgssz bytes
85  * long.  For efficiency reasons, this should be a power of two.  Also,
86  * it doesn't make sense if it is less than 8 or greater than about 256.
87  * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of
88  * two between 8 and 1024 inclusive (and panic's if it isn't).
89  */
90 struct msginfo {
91 	int	msgmax,		/* max chars in a message */
92 		msgmni,		/* max message queue identifiers */
93 		msgmnb,		/* max chars in a queue */
94 		msgtql,		/* max messages in system */
95 		msgssz,		/* size of a message segment (see notes above) */
96 		msgseg;		/* number of message segments */
97 };
98 
99 struct msgmap {
100 	short	next;		/* next segment in buffer */
101     				/* -1 -> available */
102     				/* 0..(MSGSEG-1) -> index of next segment */
103 };
104 
105 struct msqid_pool {
106 #ifdef SYSV_RWLOCK
107 	struct sysv_rwlock rwlock;
108 #else
109 	struct sysv_mutex mutex;
110 #endif
111 	struct msqid_ds_internal ds;
112 	char gen;
113 	int nfree_msgmaps;	/* # of free map entries */
114 	short free_msgmaps;	/* head of linked list of free map entries */
115 	short free_msghdrs;/* list of free msg headers */
116 	struct msg msghdrs[MSGTQL];	/* MSGTQL msg headers */
117 	struct msgmap msgmaps[MSGSEG];	/* MSGSEG msgmap structures */
118 	char msgpool[MSGMAX];		/* MSGMAX byte long msg buffer pool */
119 };
120 
121 int sysvipc_msgctl(int, int, struct msqid_ds *);
122 int sysvipc_msgget(key_t, int);
123 int sysvipc_msgsnd(int, const void *, size_t, int);
124 int sysvipc_msgrcv(int, void *, size_t, long, int);
125 
126 #endif /* !_SYSVIPC_MSG_H_ */
127