Deleted Added
full compact
sysv_msg.c (50477) sysv_msg.c (59839)
1/* $FreeBSD: head/sys/kern/sysv_msg.c 50477 1999-08-28 01:08:13Z peter $ */
1/* $FreeBSD: head/sys/kern/sysv_msg.c 59839 2000-05-01 13:33:56Z peter $ */
2
3/*
4 * Implementation of SVID messages
5 *
6 * Author: Daniel Boulet
7 *
8 * Copyright 1993 Daniel Boulet and RTMX Inc.
9 *

--- 4 unchanged lines hidden (view full) ---

14 *
15 * Redistribution in binary form may occur without any restrictions.
16 * Obviously, it would be nice if you gave credit where credit is due
17 * but requiring it would be too onerous.
18 *
19 * This software is provided ``AS IS'' without any warranties of any kind.
20 */
21
2
3/*
4 * Implementation of SVID messages
5 *
6 * Author: Daniel Boulet
7 *
8 * Copyright 1993 Daniel Boulet and RTMX Inc.
9 *

--- 4 unchanged lines hidden (view full) ---

14 *
15 * Redistribution in binary form may occur without any restrictions.
16 * Obviously, it would be nice if you gave credit where credit is due
17 * but requiring it would be too onerous.
18 *
19 * This software is provided ``AS IS'' without any warranties of any kind.
20 */
21
22#include "opt_sysvipc.h"
23
22#include <sys/param.h>
23#include <sys/systm.h>
24#include <sys/sysproto.h>
25#include <sys/kernel.h>
26#include <sys/proc.h>
27#include <sys/msg.h>
28#include <sys/sysent.h>
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/sysproto.h>
27#include <sys/kernel.h>
28#include <sys/proc.h>
29#include <sys/msg.h>
30#include <sys/sysent.h>
31#include <sys/sysctl.h>
32#include <sys/malloc.h>
29
33
34static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
35
30static void msginit __P((void *));
36static void msginit __P((void *));
31SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
32
33#define MSG_DEBUG
34#undef MSG_DEBUG_OK
35
37
38#define MSG_DEBUG
39#undef MSG_DEBUG_OK
40
36#ifndef _SYS_SYSPROTO_H_
37struct msgctl_args;
38int msgctl __P((struct proc *p, struct msgctl_args *uap));
39struct msgget_args;
40int msgget __P((struct proc *p, struct msgget_args *uap));
41struct msgsnd_args;
42int msgsnd __P((struct proc *p, struct msgsnd_args *uap));
43struct msgrcv_args;
44int msgrcv __P((struct proc *p, struct msgrcv_args *uap));
45#endif
46static void msg_freehdr __P((struct msg *msghdr));
47
48/* XXX casting to (sy_call_t *) is bogus, as usual. */
49static sy_call_t *msgcalls[] = {
50 (sy_call_t *)msgctl, (sy_call_t *)msgget,
51 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
52};
53
41static void msg_freehdr __P((struct msg *msghdr));
42
43/* XXX casting to (sy_call_t *) is bogus, as usual. */
44static sy_call_t *msgcalls[] = {
45 (sy_call_t *)msgctl, (sy_call_t *)msgget,
46 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
47};
48
49struct msg {
50 struct msg *msg_next; /* next msg in the chain */
51 long msg_type; /* type of this message */
52 /* >0 -> type of this message */
53 /* 0 -> free header */
54 u_short msg_ts; /* size of this message */
55 short msg_spot; /* location of start of msg in buffer */
56};
57
58
59#ifndef MSGSSZ
60#define MSGSSZ 8 /* Each segment must be 2^N long */
61#endif
62#ifndef MSGSEG
63#define MSGSEG 2048 /* must be less than 32767 */
64#endif
65#define MSGMAX (MSGSSZ*MSGSEG)
66#ifndef MSGMNB
67#define MSGMNB 2048 /* max # of bytes in a queue */
68#endif
69#ifndef MSGMNI
70#define MSGMNI 40
71#endif
72#ifndef MSGTQL
73#define MSGTQL 40
74#endif
75
76/*
77 * Based on the configuration parameters described in an SVR2 (yes, two)
78 * config(1m) man page.
79 *
80 * Each message is broken up and stored in segments that are msgssz bytes
81 * long. For efficiency reasons, this should be a power of two. Also,
82 * it doesn't make sense if it is less than 8 or greater than about 256.
83 * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of
84 * two between 8 and 1024 inclusive (and panic's if it isn't).
85 */
86struct msginfo msginfo = {
87 MSGMAX, /* max chars in a message */
88 MSGMNI, /* # of message queue identifiers */
89 MSGMNB, /* max chars in a queue */
90 MSGTQL, /* max messages in system */
91 MSGSSZ, /* size of a message segment */
92 /* (must be small power of 2 greater than 4) */
93 MSGSEG /* number of message segments */
94};
95
96/*
97 * macros to convert between msqid_ds's and msqid's.
98 * (specific to this implementation)
99 */
100#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm.seq << 16) & 0xffff0000))
101#define MSQID_IX(id) ((id) & 0xffff)
102#define MSQID_SEQ(id) (((id) >> 16) & 0xffff)
103
104/*
105 * The rest of this file is specific to this particular implementation.
106 */
107
108struct msgmap {
109 short next; /* next segment in buffer */
110 /* -1 -> available */
111 /* 0..(MSGSEG-1) -> index of next segment */
112};
113
114#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
115
54static int nfree_msgmaps; /* # of free map entries */
55static short free_msgmaps; /* head of linked list of free map entries */
116static int nfree_msgmaps; /* # of free map entries */
117static short free_msgmaps; /* head of linked list of free map entries */
56static struct msg *free_msghdrs; /* list of free msg headers */
57char *msgpool; /* MSGMAX byte long msg buffer pool */
58struct msgmap *msgmaps; /* MSGSEG msgmap structures */
59struct msg *msghdrs; /* MSGTQL msg headers */
60struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
118static struct msg *free_msghdrs;/* list of free msg headers */
119static char *msgpool; /* MSGMAX byte long msg buffer pool */
120static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
121static struct msg *msghdrs; /* MSGTQL msg headers */
122static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
61
123
62void
124static void
63msginit(dummy)
64 void *dummy;
65{
66 register int i;
67
125msginit(dummy)
126 void *dummy;
127{
128 register int i;
129
130 msgpool = malloc(msginfo.msgmax, M_MSG, M_WAITOK);
131 if (msgpool == NULL)
132 panic("msgpool is NULL");
133 msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK);
134 if (msgmaps == NULL)
135 panic("msgmaps is NULL");
136 msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
137 if (msghdrs == NULL)
138 panic("msghdrs is NULL");
139 msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
140 if (msqids == NULL)
141 panic("msqids is NULL");
142
68 /*
69 * msginfo.msgssz should be a power of two for efficiency reasons.
70 * It is also pretty silly if msginfo.msgssz is less than 8
71 * or greater than about 256 so ...
72 */
73
74 i = 8;
75 while (i < 1024 && i != msginfo.msgssz)

--- 34 unchanged lines hidden (view full) ---

110 if (msqids == NULL)
111 panic("msqids is NULL");
112
113 for (i = 0; i < msginfo.msgmni; i++) {
114 msqids[i].msg_qbytes = 0; /* implies entry is available */
115 msqids[i].msg_perm.seq = 0; /* reset to a known value */
116 }
117}
143 /*
144 * msginfo.msgssz should be a power of two for efficiency reasons.
145 * It is also pretty silly if msginfo.msgssz is less than 8
146 * or greater than about 256 so ...
147 */
148
149 i = 8;
150 while (i < 1024 && i != msginfo.msgssz)

--- 34 unchanged lines hidden (view full) ---

185 if (msqids == NULL)
186 panic("msqids is NULL");
187
188 for (i = 0; i < msginfo.msgmni; i++) {
189 msqids[i].msg_qbytes = 0; /* implies entry is available */
190 msqids[i].msg_perm.seq = 0; /* reset to a known value */
191 }
192}
193SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
118
119/*
120 * Entry point for all MSG calls
121 */
122int
123msgsys(p, uap)
124 struct proc *p;
125 /* XXX actually varargs. */

--- 428 unchanged lines hidden (view full) ---

554 /*
555 * Make sure that the msq queue still exists
556 */
557
558 if (msqptr->msg_qbytes == 0) {
559#ifdef MSG_DEBUG_OK
560 printf("msqid deleted\n");
561#endif
194
195/*
196 * Entry point for all MSG calls
197 */
198int
199msgsys(p, uap)
200 struct proc *p;
201 /* XXX actually varargs. */

--- 428 unchanged lines hidden (view full) ---

630 /*
631 * Make sure that the msq queue still exists
632 */
633
634 if (msqptr->msg_qbytes == 0) {
635#ifdef MSG_DEBUG_OK
636 printf("msqid deleted\n");
637#endif
562 /* The SVID says to return EIDRM. */
563#ifdef EIDRM
564 return(EIDRM);
638 return(EIDRM);
565#else
566 /* Unfortunately, BSD doesn't define that code
567 yet! */
568 return(EINVAL);
569#endif
570 }
571
572 } else {
573#ifdef MSG_DEBUG_OK
574 printf("got all the resources that we need\n");
575#endif
576 break;
577 }

--- 125 unchanged lines hidden (view full) ---

703
704 /*
705 * Make sure that the msqid_ds is still allocated.
706 */
707
708 if (msqptr->msg_qbytes == 0) {
709 msg_freehdr(msghdr);
710 wakeup((caddr_t)msqptr);
639 }
640
641 } else {
642#ifdef MSG_DEBUG_OK
643 printf("got all the resources that we need\n");
644#endif
645 break;
646 }

--- 125 unchanged lines hidden (view full) ---

772
773 /*
774 * Make sure that the msqid_ds is still allocated.
775 */
776
777 if (msqptr->msg_qbytes == 0) {
778 msg_freehdr(msghdr);
779 wakeup((caddr_t)msqptr);
711 /* The SVID says to return EIDRM. */
712#ifdef EIDRM
713 return(EIDRM);
780 return(EIDRM);
714#else
715 /* Unfortunately, BSD doesn't define that code yet! */
716 return(EINVAL);
717#endif
718 }
719
720 /*
721 * Put the message into the queue
722 */
723
724 if (msqptr->msg_first == NULL) {
725 msqptr->msg_first = msghdr;

--- 204 unchanged lines hidden (view full) ---

930 * Make sure that the msq queue still exists
931 */
932
933 if (msqptr->msg_qbytes == 0 ||
934 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
935#ifdef MSG_DEBUG_OK
936 printf("msqid deleted\n");
937#endif
781 }
782
783 /*
784 * Put the message into the queue
785 */
786
787 if (msqptr->msg_first == NULL) {
788 msqptr->msg_first = msghdr;

--- 204 unchanged lines hidden (view full) ---

993 * Make sure that the msq queue still exists
994 */
995
996 if (msqptr->msg_qbytes == 0 ||
997 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
998#ifdef MSG_DEBUG_OK
999 printf("msqid deleted\n");
1000#endif
938 /* The SVID says to return EIDRM. */
939#ifdef EIDRM
940 return(EIDRM);
1001 return(EIDRM);
941#else
942 /* Unfortunately, BSD doesn't define that code yet! */
943 return(EINVAL);
944#endif
945 }
946 }
947
948 /*
949 * Return the message to the user.
950 *
951 * First, do the bookkeeping (before we risk being interrupted).
952 */

--- 75 unchanged lines hidden ---
1002 }
1003 }
1004
1005 /*
1006 * Return the message to the user.
1007 *
1008 * First, do the bookkeeping (before we risk being interrupted).
1009 */

--- 75 unchanged lines hidden ---