Move the MSG* and SEM* options to opt_sysvipc.h
Remove evil allocation macros from machdep.c (why was that there???) and use malloc() instead. Move paramters out of param.h and into the code itself. Move a bunch of internal definitions from public sys/*.h headers (without #ifdef _KERNEL even) into the code itself. I had hoped to make some of this more dynamic, but the cost of doing wakeups on all sleeping processes on old arrays was too frightening. The other possibility is to initialize on the first use, and allow dynamic sysctl changes to parameters right until that point. That would allow /etc/rc.sysctl to change SEM* and MSG* defaults as we presently do with SHM*, but without the nightmare of changing a running system.
This commit is contained in:
parent
09dd94d856
commit
ab063af911
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59839
@ -91,7 +91,6 @@
|
||||
#include "opt_compat.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_simos.h"
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_msgbuf.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -141,14 +140,6 @@
|
||||
#include <miscfs/procfs/procfs.h>
|
||||
#include <machine/sigframe.h>
|
||||
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
struct proc* curproc;
|
||||
struct proc* fpcurproc;
|
||||
struct pcb* curpcb;
|
||||
@ -328,18 +319,6 @@ cpu_startup(dummy)
|
||||
|
||||
valloc(callout, struct callout, ncallout);
|
||||
valloc(callwheel, struct callout_tailq, callwheelsize);
|
||||
#ifdef SYSVSEM
|
||||
valloc(sema, struct semid_ds, seminfo.semmni);
|
||||
valloc(sem, struct sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
valloc(msgpool, char, msginfo.msgmax);
|
||||
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
||||
valloc(msghdrs, struct msg, msginfo.msgtql);
|
||||
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "opt_msgbuf.h"
|
||||
#include "opt_perfmon.h"
|
||||
#include "opt_smp.h"
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_userconfig.h"
|
||||
|
||||
@ -73,14 +72,6 @@
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <sys/lock.h>
|
||||
@ -325,18 +316,6 @@ cpu_startup(dummy)
|
||||
|
||||
valloc(callout, struct callout, ncallout);
|
||||
valloc(callwheel, struct callout_tailq, callwheelsize);
|
||||
#ifdef SYSVSEM
|
||||
valloc(sema, struct semid_ds, seminfo.semmni);
|
||||
valloc(sem, struct sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
valloc(msgpool, char, msginfo.msgmax);
|
||||
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
||||
valloc(msghdrs, struct msg, msginfo.msgtql);
|
||||
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
|
||||
|
@ -73,6 +73,18 @@ SHMMAXPGS opt_sysvipc.h
|
||||
SHMMIN opt_sysvipc.h
|
||||
SHMMNI opt_sysvipc.h
|
||||
SHMSEG opt_sysvipc.h
|
||||
SEMMAP opt_sysvipc.h
|
||||
SEMMNI opt_sysvipc.h
|
||||
SEMMNS opt_sysvipc.h
|
||||
SEMMNU opt_sysvipc.h
|
||||
SEMMSL opt_sysvipc.h
|
||||
SEMOPM opt_sysvipc.h
|
||||
SEMUME opt_sysvipc.h
|
||||
MSGMNB opt_sysvipc.h
|
||||
MSGMNI opt_sysvipc.h
|
||||
MSGSEG opt_sysvipc.h
|
||||
MSGSSZ opt_sysvipc.h
|
||||
MSGTQL opt_sysvipc.h
|
||||
UCONSOLE
|
||||
ICMP_BANDLIM
|
||||
VFS_AIO
|
||||
@ -138,21 +150,9 @@ UNION
|
||||
HZ opt_param.h
|
||||
MAXFILES opt_param.h
|
||||
MAXUSERS opt_param.h
|
||||
MSGMNB opt_param.h
|
||||
MSGMNI opt_param.h
|
||||
MSGSEG opt_param.h
|
||||
MSGSSZ opt_param.h
|
||||
MSGTQL opt_param.h
|
||||
NBUF opt_param.h
|
||||
NMBCLUSTERS opt_param.h
|
||||
NSFBUFS opt_param.h
|
||||
SEMMAP opt_param.h
|
||||
SEMMNI opt_param.h
|
||||
SEMMNS opt_param.h
|
||||
SEMMNU opt_param.h
|
||||
SEMMSL opt_param.h
|
||||
SEMOPM opt_param.h
|
||||
SEMUME opt_param.h
|
||||
|
||||
# Generic SCSI options.
|
||||
CAM_MAX_HIGHPOWER opt_cam.h
|
||||
|
@ -41,18 +41,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_param.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System parameter formulae.
|
||||
*
|
||||
@ -86,43 +78,6 @@ int mbuf_wait = 32; /* mbuf sleep time in ticks */
|
||||
#endif
|
||||
int nsfbufs = NSFBUFS;
|
||||
|
||||
/*
|
||||
* Values in support of System V compatible semaphores.
|
||||
*/
|
||||
|
||||
#ifdef SYSVSEM
|
||||
|
||||
struct seminfo seminfo = {
|
||||
SEMMAP, /* # of entries in semaphore map */
|
||||
SEMMNI, /* # of semaphore identifiers */
|
||||
SEMMNS, /* # of semaphores in system */
|
||||
SEMMNU, /* # of undo structures in system */
|
||||
SEMMSL, /* max # of semaphores per id */
|
||||
SEMOPM, /* max # of operations per semop call */
|
||||
SEMUME, /* max # of undo entries per process */
|
||||
SEMUSZ, /* size in bytes of undo structure */
|
||||
SEMVMX, /* semaphore maximum value */
|
||||
SEMAEM /* adjust on exit max value */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Values in support of System V compatible messages.
|
||||
*/
|
||||
|
||||
#ifdef SYSVMSG
|
||||
|
||||
struct msginfo msginfo = {
|
||||
MSGMAX, /* max chars in a message */
|
||||
MSGMNI, /* # of message queue identifiers */
|
||||
MSGMNB, /* max chars in a queue */
|
||||
MSGTQL, /* max messages in system */
|
||||
MSGSSZ, /* size of a message segment */
|
||||
/* (must be small power of 2 greater than 4) */
|
||||
MSGSEG /* number of message segments */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These may be set to nonzero here or by patching.
|
||||
* If they are nonzero at bootstrap time then they are
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "opt_msgbuf.h"
|
||||
#include "opt_perfmon.h"
|
||||
#include "opt_smp.h"
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_userconfig.h"
|
||||
|
||||
@ -73,14 +72,6 @@
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <sys/lock.h>
|
||||
@ -325,18 +316,6 @@ cpu_startup(dummy)
|
||||
|
||||
valloc(callout, struct callout, ncallout);
|
||||
valloc(callwheel, struct callout_tailq, callwheelsize);
|
||||
#ifdef SYSVSEM
|
||||
valloc(sema, struct semid_ds, seminfo.semmni);
|
||||
valloc(sem, struct sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
valloc(msgpool, char, msginfo.msgmax);
|
||||
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
||||
valloc(msghdrs, struct msg, msginfo.msgtql);
|
||||
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
|
||||
|
@ -41,18 +41,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_param.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System parameter formulae.
|
||||
*
|
||||
@ -86,43 +78,6 @@ int mbuf_wait = 32; /* mbuf sleep time in ticks */
|
||||
#endif
|
||||
int nsfbufs = NSFBUFS;
|
||||
|
||||
/*
|
||||
* Values in support of System V compatible semaphores.
|
||||
*/
|
||||
|
||||
#ifdef SYSVSEM
|
||||
|
||||
struct seminfo seminfo = {
|
||||
SEMMAP, /* # of entries in semaphore map */
|
||||
SEMMNI, /* # of semaphore identifiers */
|
||||
SEMMNS, /* # of semaphores in system */
|
||||
SEMMNU, /* # of undo structures in system */
|
||||
SEMMSL, /* max # of semaphores per id */
|
||||
SEMOPM, /* max # of operations per semop call */
|
||||
SEMUME, /* max # of undo entries per process */
|
||||
SEMUSZ, /* size in bytes of undo structure */
|
||||
SEMVMX, /* semaphore maximum value */
|
||||
SEMAEM /* adjust on exit max value */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Values in support of System V compatible messages.
|
||||
*/
|
||||
|
||||
#ifdef SYSVMSG
|
||||
|
||||
struct msginfo msginfo = {
|
||||
MSGMAX, /* max chars in a message */
|
||||
MSGMNI, /* # of message queue identifiers */
|
||||
MSGMNB, /* max chars in a queue */
|
||||
MSGTQL, /* max messages in system */
|
||||
MSGSSZ, /* size of a message segment */
|
||||
/* (must be small power of 2 greater than 4) */
|
||||
MSGSEG /* number of message segments */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These may be set to nonzero here or by patching.
|
||||
* If they are nonzero at bootstrap time then they are
|
||||
|
@ -19,6 +19,8 @@
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*/
|
||||
|
||||
#include "opt_sysvipc.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysproto.h>
|
||||
@ -26,23 +28,16 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
|
||||
|
||||
static void msginit __P((void *));
|
||||
SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
|
||||
|
||||
#define MSG_DEBUG
|
||||
#undef MSG_DEBUG_OK
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct msgctl_args;
|
||||
int msgctl __P((struct proc *p, struct msgctl_args *uap));
|
||||
struct msgget_args;
|
||||
int msgget __P((struct proc *p, struct msgget_args *uap));
|
||||
struct msgsnd_args;
|
||||
int msgsnd __P((struct proc *p, struct msgsnd_args *uap));
|
||||
struct msgrcv_args;
|
||||
int msgrcv __P((struct proc *p, struct msgrcv_args *uap));
|
||||
#endif
|
||||
static void msg_freehdr __P((struct msg *msghdr));
|
||||
|
||||
/* XXX casting to (sy_call_t *) is bogus, as usual. */
|
||||
@ -51,20 +46,100 @@ static sy_call_t *msgcalls[] = {
|
||||
(sy_call_t *)msgsnd, (sy_call_t *)msgrcv
|
||||
};
|
||||
|
||||
struct msg {
|
||||
struct msg *msg_next; /* next msg in the chain */
|
||||
long msg_type; /* type of this message */
|
||||
/* >0 -> type of this message */
|
||||
/* 0 -> free header */
|
||||
u_short msg_ts; /* size of this message */
|
||||
short msg_spot; /* location of start of msg in buffer */
|
||||
};
|
||||
|
||||
|
||||
#ifndef MSGSSZ
|
||||
#define MSGSSZ 8 /* Each segment must be 2^N long */
|
||||
#endif
|
||||
#ifndef MSGSEG
|
||||
#define MSGSEG 2048 /* must be less than 32767 */
|
||||
#endif
|
||||
#define MSGMAX (MSGSSZ*MSGSEG)
|
||||
#ifndef MSGMNB
|
||||
#define MSGMNB 2048 /* max # of bytes in a queue */
|
||||
#endif
|
||||
#ifndef MSGMNI
|
||||
#define MSGMNI 40
|
||||
#endif
|
||||
#ifndef MSGTQL
|
||||
#define MSGTQL 40
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Based on the configuration parameters described in an SVR2 (yes, two)
|
||||
* config(1m) man page.
|
||||
*
|
||||
* Each message is broken up and stored in segments that are msgssz bytes
|
||||
* long. For efficiency reasons, this should be a power of two. Also,
|
||||
* it doesn't make sense if it is less than 8 or greater than about 256.
|
||||
* Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of
|
||||
* two between 8 and 1024 inclusive (and panic's if it isn't).
|
||||
*/
|
||||
struct msginfo msginfo = {
|
||||
MSGMAX, /* max chars in a message */
|
||||
MSGMNI, /* # of message queue identifiers */
|
||||
MSGMNB, /* max chars in a queue */
|
||||
MSGTQL, /* max messages in system */
|
||||
MSGSSZ, /* size of a message segment */
|
||||
/* (must be small power of 2 greater than 4) */
|
||||
MSGSEG /* number of message segments */
|
||||
};
|
||||
|
||||
/*
|
||||
* macros to convert between msqid_ds's and msqid's.
|
||||
* (specific to this implementation)
|
||||
*/
|
||||
#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm.seq << 16) & 0xffff0000))
|
||||
#define MSQID_IX(id) ((id) & 0xffff)
|
||||
#define MSQID_SEQ(id) (((id) >> 16) & 0xffff)
|
||||
|
||||
/*
|
||||
* The rest of this file is specific to this particular implementation.
|
||||
*/
|
||||
|
||||
struct msgmap {
|
||||
short next; /* next segment in buffer */
|
||||
/* -1 -> available */
|
||||
/* 0..(MSGSEG-1) -> index of next segment */
|
||||
};
|
||||
|
||||
#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
|
||||
|
||||
static int nfree_msgmaps; /* # of free map entries */
|
||||
static short free_msgmaps; /* head of linked list of free map entries */
|
||||
static struct msg *free_msghdrs; /* list of free msg headers */
|
||||
char *msgpool; /* MSGMAX byte long msg buffer pool */
|
||||
struct msgmap *msgmaps; /* MSGSEG msgmap structures */
|
||||
struct msg *msghdrs; /* MSGTQL msg headers */
|
||||
struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
|
||||
static struct msg *free_msghdrs;/* list of free msg headers */
|
||||
static char *msgpool; /* MSGMAX byte long msg buffer pool */
|
||||
static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
|
||||
static struct msg *msghdrs; /* MSGTQL msg headers */
|
||||
static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
|
||||
|
||||
void
|
||||
static void
|
||||
msginit(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
register int i;
|
||||
|
||||
msgpool = malloc(msginfo.msgmax, M_MSG, M_WAITOK);
|
||||
if (msgpool == NULL)
|
||||
panic("msgpool is NULL");
|
||||
msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK);
|
||||
if (msgmaps == NULL)
|
||||
panic("msgmaps is NULL");
|
||||
msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
|
||||
if (msghdrs == NULL)
|
||||
panic("msghdrs is NULL");
|
||||
msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
|
||||
if (msqids == NULL)
|
||||
panic("msqids is NULL");
|
||||
|
||||
/*
|
||||
* msginfo.msgssz should be a power of two for efficiency reasons.
|
||||
* It is also pretty silly if msginfo.msgssz is less than 8
|
||||
@ -115,6 +190,7 @@ msginit(dummy)
|
||||
msqids[i].msg_perm.seq = 0; /* reset to a known value */
|
||||
}
|
||||
}
|
||||
SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
|
||||
|
||||
/*
|
||||
* Entry point for all MSG calls
|
||||
@ -559,14 +635,7 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msqid deleted\n");
|
||||
#endif
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code
|
||||
yet! */
|
||||
return(EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -708,13 +777,7 @@ msgsnd(p, uap)
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code yet! */
|
||||
return(EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -935,13 +998,7 @@ msgrcv(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msqid deleted\n");
|
||||
#endif
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code yet! */
|
||||
return(EINVAL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*/
|
||||
|
||||
#include "opt_sysvipc.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysproto.h>
|
||||
@ -15,9 +17,12 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
|
||||
|
||||
static void seminit __P((void *));
|
||||
SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL)
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct __semctl_args;
|
||||
@ -40,19 +45,135 @@ static sy_call_t *semcalls[] = {
|
||||
};
|
||||
|
||||
static int semtot = 0;
|
||||
struct semid_ds *sema; /* semaphore id pool */
|
||||
struct sem *sem; /* semaphore pool */
|
||||
static struct sem_undo *semu_list; /* list of active undo structures */
|
||||
int *semu; /* undo structure pool */
|
||||
static struct semid_ds *sema; /* semaphore id pool */
|
||||
static struct sem *sem; /* semaphore pool */
|
||||
static struct sem_undo *semu_list; /* list of active undo structures */
|
||||
static int *semu; /* undo structure pool */
|
||||
|
||||
void
|
||||
struct sem {
|
||||
u_short semval; /* semaphore value */
|
||||
pid_t sempid; /* pid of last operation */
|
||||
u_short semncnt; /* # awaiting semval > cval */
|
||||
u_short semzcnt; /* # awaiting semval = 0 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Undo structure (one per process)
|
||||
*/
|
||||
struct sem_undo {
|
||||
struct sem_undo *un_next; /* ptr to next active undo structure */
|
||||
struct proc *un_proc; /* owner of this structure */
|
||||
short un_cnt; /* # of active entries */
|
||||
struct undo {
|
||||
short un_adjval; /* adjust on exit values */
|
||||
short un_num; /* semaphore # */
|
||||
int un_id; /* semid */
|
||||
} un_ent[1]; /* undo entries */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration parameters
|
||||
*/
|
||||
#ifndef SEMMNI
|
||||
#define SEMMNI 10 /* # of semaphore identifiers */
|
||||
#endif
|
||||
#ifndef SEMMNS
|
||||
#define SEMMNS 60 /* # of semaphores in system */
|
||||
#endif
|
||||
#ifndef SEMUME
|
||||
#define SEMUME 10 /* max # of undo entries per process */
|
||||
#endif
|
||||
#ifndef SEMMNU
|
||||
#define SEMMNU 30 /* # of undo structures in system */
|
||||
#endif
|
||||
|
||||
/* shouldn't need tuning */
|
||||
#ifndef SEMMAP
|
||||
#define SEMMAP 30 /* # of entries in semaphore map */
|
||||
#endif
|
||||
#ifndef SEMMSL
|
||||
#define SEMMSL SEMMNS /* max # of semaphores per id */
|
||||
#endif
|
||||
#ifndef SEMOPM
|
||||
#define SEMOPM 100 /* max # of operations per semop call */
|
||||
#endif
|
||||
|
||||
#define SEMVMX 32767 /* semaphore maximum value */
|
||||
#define SEMAEM 16384 /* adjust on exit max value */
|
||||
|
||||
/*
|
||||
* Due to the way semaphore memory is allocated, we have to ensure that
|
||||
* SEMUSZ is properly aligned.
|
||||
*/
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
|
||||
#endif
|
||||
|
||||
#define SEM_ALIGN(bytes) (((bytes) + (sizeof(long) - 1)) & ~(sizeof(long) - 1))
|
||||
|
||||
/* actual size of an undo structure */
|
||||
#define SEMUSZ SEM_ALIGN(offsetof(struct sem_undo, un_ent[SEMUME]))
|
||||
|
||||
/*
|
||||
* Macro to find a particular sem_undo vector
|
||||
*/
|
||||
#define SEMU(ix) ((struct sem_undo *)(((intptr_t)semu)+ix * seminfo.semusz))
|
||||
|
||||
/*
|
||||
* semaphore info struct
|
||||
*/
|
||||
struct seminfo seminfo = {
|
||||
SEMMAP, /* # of entries in semaphore map */
|
||||
SEMMNI, /* # of semaphore identifiers */
|
||||
SEMMNS, /* # of semaphores in system */
|
||||
SEMMNU, /* # of undo structures in system */
|
||||
SEMMSL, /* max # of semaphores per id */
|
||||
SEMOPM, /* max # of operations per semop call */
|
||||
SEMUME, /* max # of undo entries per process */
|
||||
SEMUSZ, /* size in bytes of undo structure */
|
||||
SEMVMX, /* semaphore maximum value */
|
||||
SEMAEM /* adjust on exit max value */
|
||||
};
|
||||
|
||||
SYSCTL_DECL(_kern_ipc);
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semmap, CTLFLAG_RW, &seminfo.semmap, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semmni, CTLFLAG_RD, &seminfo.semmni, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semmns, CTLFLAG_RD, &seminfo.semmns, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semmnu, CTLFLAG_RD, &seminfo.semmnu, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semmsl, CTLFLAG_RW, &seminfo.semmsl, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semopm, CTLFLAG_RD, &seminfo.semopm, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semume, CTLFLAG_RD, &seminfo.semume, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semusz, CTLFLAG_RD, &seminfo.semusz, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0, "");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0, "");
|
||||
|
||||
#if 0
|
||||
RO seminfo.semmap /* SEMMAP unused */
|
||||
RO seminfo.semmni
|
||||
RO seminfo.semmns
|
||||
RO seminfo.semmnu /* undo entries per system */
|
||||
RW seminfo.semmsl
|
||||
RO seminfo.semopm /* SEMOPM unused */
|
||||
RO seminfo.semume
|
||||
RO seminfo.semusz /* param - derived from SEMUME for per-proc sizeof */
|
||||
RO seminfo.semvmx /* SEMVMX unused - user param */
|
||||
RO seminfo.semaem /* SEMAEM unused - user param */
|
||||
#endif
|
||||
|
||||
static void
|
||||
seminit(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
register int i;
|
||||
|
||||
sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK);
|
||||
if (sem == NULL)
|
||||
panic("sem is NULL");
|
||||
sema = malloc(sizeof(struct semid_ds) * seminfo.semmni, M_SEM, M_WAITOK);
|
||||
if (sema == NULL)
|
||||
panic("sema is NULL");
|
||||
semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK);
|
||||
if (semu == NULL)
|
||||
panic("semu is NULL");
|
||||
|
||||
@ -66,6 +187,7 @@ seminit(dummy)
|
||||
}
|
||||
semu_list = NULL;
|
||||
}
|
||||
SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL)
|
||||
|
||||
/*
|
||||
* Entry point for all SEM calls
|
||||
@ -708,15 +830,8 @@ semop(p, uap)
|
||||
* Make sure that the semaphore still exists
|
||||
*/
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||
/* The man page says to return EIDRM. */
|
||||
/* Unfortunately, BSD doesn't define that code! */
|
||||
#ifdef EIDRM
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
||||
return(EIDRM);
|
||||
#else
|
||||
return(EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The semaphore is still alive. Readjust the count of
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "opt_msgbuf.h"
|
||||
#include "opt_perfmon.h"
|
||||
#include "opt_smp.h"
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_userconfig.h"
|
||||
|
||||
@ -73,14 +72,6 @@
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <sys/lock.h>
|
||||
@ -338,18 +329,6 @@ cpu_startup(dummy)
|
||||
|
||||
valloc(callout, struct callout, ncallout);
|
||||
valloc(callwheel, struct callout_tailq, callwheelsize);
|
||||
#ifdef SYSVSEM
|
||||
valloc(sema, struct semid_ds, seminfo.semmni);
|
||||
valloc(sem, struct sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
valloc(msgpool, char, msginfo.msgmax);
|
||||
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
||||
valloc(msghdrs, struct msg, msginfo.msgtql);
|
||||
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "opt_msgbuf.h"
|
||||
#include "opt_perfmon.h"
|
||||
#include "opt_smp.h"
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_userconfig.h"
|
||||
|
||||
@ -73,14 +72,6 @@
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#ifdef SYSVMSG
|
||||
#include <sys/msg.h>
|
||||
#endif
|
||||
|
||||
#ifdef SYSVSEM
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <sys/lock.h>
|
||||
@ -338,18 +329,6 @@ cpu_startup(dummy)
|
||||
|
||||
valloc(callout, struct callout, ncallout);
|
||||
valloc(callwheel, struct callout_tailq, callwheelsize);
|
||||
#ifdef SYSVSEM
|
||||
valloc(sema, struct semid_ds, seminfo.semmni);
|
||||
valloc(sem, struct sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
valloc(msgpool, char, msginfo.msgmax);
|
||||
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
||||
valloc(msghdrs, struct msg, msginfo.msgtql);
|
||||
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
#define MSG_NOERROR 010000 /* don't complain about too long msgs */
|
||||
|
||||
struct msg;
|
||||
|
||||
struct msqid_ds {
|
||||
struct ipc_perm msg_perm; /* msg queue permission bits */
|
||||
struct msg *msg_first; /* first message in the queue */
|
||||
@ -50,15 +52,6 @@ struct msqid_ds {
|
||||
long msg_pad4[4];
|
||||
};
|
||||
|
||||
struct msg {
|
||||
struct msg *msg_next; /* next msg in the chain */
|
||||
long msg_type; /* type of this message */
|
||||
/* >0 -> type of this message */
|
||||
/* 0 -> free header */
|
||||
u_short msg_ts; /* size of this message */
|
||||
short msg_spot; /* location of start of msg in buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure describing a message. The SVID doesn't suggest any
|
||||
* particular name for this structure. There is a reference in the
|
||||
@ -74,6 +67,8 @@ struct mymsg {
|
||||
char mtext[1]; /* message body */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* Based on the configuration parameters described in an SVR2 (yes, two)
|
||||
* config(1m) man page.
|
||||
@ -92,58 +87,11 @@ struct msginfo {
|
||||
msgssz, /* size of a message segment (see notes above) */
|
||||
msgseg; /* number of message segments */
|
||||
};
|
||||
#ifdef _KERNEL
|
||||
extern struct msginfo msginfo;
|
||||
|
||||
#ifndef MSGSSZ
|
||||
#define MSGSSZ 8 /* Each segment must be 2^N long */
|
||||
#endif
|
||||
#ifndef MSGSEG
|
||||
#define MSGSEG 2048 /* must be less than 32767 */
|
||||
#endif
|
||||
#define MSGMAX (MSGSSZ*MSGSEG)
|
||||
#ifndef MSGMNB
|
||||
#define MSGMNB 2048 /* max # of bytes in a queue */
|
||||
#endif
|
||||
#ifndef MSGMNI
|
||||
#define MSGMNI 40
|
||||
#endif
|
||||
#ifndef MSGTQL
|
||||
#define MSGTQL 40
|
||||
#endif
|
||||
|
||||
/*
|
||||
* macros to convert between msqid_ds's and msqid's.
|
||||
* (specific to this implementation)
|
||||
*/
|
||||
#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm.seq << 16) & 0xffff0000))
|
||||
#define MSQID_IX(id) ((id) & 0xffff)
|
||||
#define MSQID_SEQ(id) (((id) >> 16) & 0xffff)
|
||||
|
||||
/*
|
||||
* The rest of this file is specific to this particular implementation.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Stuff allocated in machdep.h
|
||||
*/
|
||||
struct msgmap {
|
||||
short next; /* next segment in buffer */
|
||||
/* -1 -> available */
|
||||
/* 0..(MSGSEG-1) -> index of next segment */
|
||||
};
|
||||
|
||||
extern char *msgpool; /* MSGMAX byte long msg buffer pool */
|
||||
extern struct msgmap *msgmaps; /* MSGSEG msgmap structures */
|
||||
extern struct msg *msghdrs; /* MSGTQL msg headers */
|
||||
extern struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
|
||||
|
||||
#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
@ -12,12 +12,7 @@
|
||||
|
||||
#include <sys/ipc.h>
|
||||
|
||||
struct sem {
|
||||
u_short semval; /* semaphore value */
|
||||
pid_t sempid; /* pid of last operation */
|
||||
u_short semncnt; /* # awaiting semval > cval */
|
||||
u_short semzcnt; /* # awaiting semval = 0 */
|
||||
};
|
||||
struct sem;
|
||||
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm; /* operation permission struct */
|
||||
@ -71,26 +66,6 @@ union semun {
|
||||
#define SEM_R 0400 /* read permission */
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Kernel implementation stuff
|
||||
*/
|
||||
#define SEMVMX 32767 /* semaphore maximum value */
|
||||
#define SEMAEM 16384 /* adjust on exit max value */
|
||||
|
||||
|
||||
/*
|
||||
* Undo structure (one per process)
|
||||
*/
|
||||
struct sem_undo {
|
||||
struct sem_undo *un_next; /* ptr to next active undo structure */
|
||||
struct proc *un_proc; /* owner of this structure */
|
||||
short un_cnt; /* # of active entries */
|
||||
struct undo {
|
||||
short un_adjval; /* adjust on exit values */
|
||||
short un_num; /* semaphore # */
|
||||
int un_id; /* semid */
|
||||
} un_ent[1]; /* undo entries */
|
||||
};
|
||||
|
||||
/*
|
||||
* semaphore info struct
|
||||
@ -113,52 +88,6 @@ extern struct seminfo seminfo;
|
||||
#define SEM_ALLOC 01000 /* semaphore is allocated */
|
||||
#define SEM_DEST 02000 /* semaphore will be destroyed on last detach */
|
||||
|
||||
/*
|
||||
* Configuration parameters
|
||||
*/
|
||||
#ifndef SEMMNI
|
||||
#define SEMMNI 10 /* # of semaphore identifiers */
|
||||
#endif
|
||||
#ifndef SEMMNS
|
||||
#define SEMMNS 60 /* # of semaphores in system */
|
||||
#endif
|
||||
#ifndef SEMUME
|
||||
#define SEMUME 10 /* max # of undo entries per process */
|
||||
#endif
|
||||
#ifndef SEMMNU
|
||||
#define SEMMNU 30 /* # of undo structures in system */
|
||||
#endif
|
||||
|
||||
/* shouldn't need tuning */
|
||||
#ifndef SEMMAP
|
||||
#define SEMMAP 30 /* # of entries in semaphore map */
|
||||
#endif
|
||||
#ifndef SEMMSL
|
||||
#define SEMMSL SEMMNS /* max # of semaphores per id */
|
||||
#endif
|
||||
#ifndef SEMOPM
|
||||
#define SEMOPM 100 /* max # of operations per semop call */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Due to the way semaphore memory is allocated, we have to ensure that
|
||||
* SEMUSZ is properly aligned.
|
||||
*/
|
||||
|
||||
#define SEM_ALIGN(bytes) (((bytes) + (sizeof(long) - 1)) & ~(sizeof(long) - 1))
|
||||
|
||||
/* actual size of an undo structure */
|
||||
#define SEMUSZ SEM_ALIGN(offsetof(struct sem_undo, un_ent[SEMUME]))
|
||||
|
||||
extern struct semid_ds *sema; /* semaphore id pool */
|
||||
extern struct sem *sem; /* semaphore pool */
|
||||
extern int *semu; /* undo structure pool */
|
||||
|
||||
/*
|
||||
* Macro to find a particular sem_undo vector
|
||||
*/
|
||||
#define SEMU(ix) ((struct sem_undo *)(((intptr_t)semu)+ix * seminfo.semusz))
|
||||
|
||||
/*
|
||||
* Process sem_undo vectors at proc exit.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user