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 --- |