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