sysv_sem.c (59828) | sysv_sem.c (59839) |
---|---|
1/* $FreeBSD: head/sys/kern/sysv_sem.c 59828 2000-05-01 11:13:41Z peter $ */ | 1/* $FreeBSD: head/sys/kern/sysv_sem.c 59839 2000-05-01 13:33:56Z peter $ */ |
2 3/* 4 * Implementation of SVID semaphores 5 * 6 * Author: Daniel Boulet 7 * 8 * This software is provided ``AS IS'' without any warranties of any kind. 9 */ 10 | 2 3/* 4 * Implementation of SVID semaphores 5 * 6 * Author: Daniel Boulet 7 * 8 * This software is provided ``AS IS'' without any warranties of any kind. 9 */ 10 |
11#include "opt_sysvipc.h" 12 |
|
11#include <sys/param.h> 12#include <sys/systm.h> 13#include <sys/sysproto.h> 14#include <sys/kernel.h> 15#include <sys/proc.h> 16#include <sys/sem.h> 17#include <sys/sysent.h> | 13#include <sys/param.h> 14#include <sys/systm.h> 15#include <sys/sysproto.h> 16#include <sys/kernel.h> 17#include <sys/proc.h> 18#include <sys/sem.h> 19#include <sys/sysent.h> |
20#include <sys/sysctl.h> 21#include <sys/malloc.h> |
|
18 | 22 |
23static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); 24 |
|
19static void seminit __P((void *)); | 25static void seminit __P((void *)); |
20SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) | |
21 22#ifndef _SYS_SYSPROTO_H_ 23struct __semctl_args; 24int __semctl __P((struct proc *p, struct __semctl_args *uap)); 25struct semget_args; 26int semget __P((struct proc *p, struct semget_args *uap)); 27struct semop_args; 28int semop __P((struct proc *p, struct semop_args *uap)); --- 6 unchanged lines hidden (view full) --- 35 36/* XXX casting to (sy_call_t *) is bogus, as usual. */ 37static sy_call_t *semcalls[] = { 38 (sy_call_t *)__semctl, (sy_call_t *)semget, 39 (sy_call_t *)semop 40}; 41 42static int semtot = 0; | 26 27#ifndef _SYS_SYSPROTO_H_ 28struct __semctl_args; 29int __semctl __P((struct proc *p, struct __semctl_args *uap)); 30struct semget_args; 31int semget __P((struct proc *p, struct semget_args *uap)); 32struct semop_args; 33int semop __P((struct proc *p, struct semop_args *uap)); --- 6 unchanged lines hidden (view full) --- 40 41/* XXX casting to (sy_call_t *) is bogus, as usual. */ 42static sy_call_t *semcalls[] = { 43 (sy_call_t *)__semctl, (sy_call_t *)semget, 44 (sy_call_t *)semop 45}; 46 47static int semtot = 0; |
43struct semid_ds *sema; /* semaphore id pool */ 44struct sem *sem; /* semaphore pool */ 45static struct sem_undo *semu_list; /* list of active undo structures */ 46int *semu; /* undo structure pool */ | 48static struct semid_ds *sema; /* semaphore id pool */ 49static struct sem *sem; /* semaphore pool */ 50static struct sem_undo *semu_list; /* list of active undo structures */ 51static int *semu; /* undo structure pool */ |
47 | 52 |
48void | 53struct sem { 54 u_short semval; /* semaphore value */ 55 pid_t sempid; /* pid of last operation */ 56 u_short semncnt; /* # awaiting semval > cval */ 57 u_short semzcnt; /* # awaiting semval = 0 */ 58}; 59 60/* 61 * Undo structure (one per process) 62 */ 63struct sem_undo { 64 struct sem_undo *un_next; /* ptr to next active undo structure */ 65 struct proc *un_proc; /* owner of this structure */ 66 short un_cnt; /* # of active entries */ 67 struct undo { 68 short un_adjval; /* adjust on exit values */ 69 short un_num; /* semaphore # */ 70 int un_id; /* semid */ 71 } un_ent[1]; /* undo entries */ 72}; 73 74/* 75 * Configuration parameters 76 */ 77#ifndef SEMMNI 78#define SEMMNI 10 /* # of semaphore identifiers */ 79#endif 80#ifndef SEMMNS 81#define SEMMNS 60 /* # of semaphores in system */ 82#endif 83#ifndef SEMUME 84#define SEMUME 10 /* max # of undo entries per process */ 85#endif 86#ifndef SEMMNU 87#define SEMMNU 30 /* # of undo structures in system */ 88#endif 89 90/* shouldn't need tuning */ 91#ifndef SEMMAP 92#define SEMMAP 30 /* # of entries in semaphore map */ 93#endif 94#ifndef SEMMSL 95#define SEMMSL SEMMNS /* max # of semaphores per id */ 96#endif 97#ifndef SEMOPM 98#define SEMOPM 100 /* max # of operations per semop call */ 99#endif 100 101#define SEMVMX 32767 /* semaphore maximum value */ 102#define SEMAEM 16384 /* adjust on exit max value */ 103 104/* 105 * Due to the way semaphore memory is allocated, we have to ensure that 106 * SEMUSZ is properly aligned. 107 */ 108 109#ifndef offsetof 110#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 111#endif 112 113#define SEM_ALIGN(bytes) (((bytes) + (sizeof(long) - 1)) & ~(sizeof(long) - 1)) 114 115/* actual size of an undo structure */ 116#define SEMUSZ SEM_ALIGN(offsetof(struct sem_undo, un_ent[SEMUME])) 117 118/* 119 * Macro to find a particular sem_undo vector 120 */ 121#define SEMU(ix) ((struct sem_undo *)(((intptr_t)semu)+ix * seminfo.semusz)) 122 123/* 124 * semaphore info struct 125 */ 126struct seminfo seminfo = { 127 SEMMAP, /* # of entries in semaphore map */ 128 SEMMNI, /* # of semaphore identifiers */ 129 SEMMNS, /* # of semaphores in system */ 130 SEMMNU, /* # of undo structures in system */ 131 SEMMSL, /* max # of semaphores per id */ 132 SEMOPM, /* max # of operations per semop call */ 133 SEMUME, /* max # of undo entries per process */ 134 SEMUSZ, /* size in bytes of undo structure */ 135 SEMVMX, /* semaphore maximum value */ 136 SEMAEM /* adjust on exit max value */ 137}; 138 139SYSCTL_DECL(_kern_ipc); 140SYSCTL_INT(_kern_ipc, OID_AUTO, semmap, CTLFLAG_RW, &seminfo.semmap, 0, ""); 141SYSCTL_INT(_kern_ipc, OID_AUTO, semmni, CTLFLAG_RD, &seminfo.semmni, 0, ""); 142SYSCTL_INT(_kern_ipc, OID_AUTO, semmns, CTLFLAG_RD, &seminfo.semmns, 0, ""); 143SYSCTL_INT(_kern_ipc, OID_AUTO, semmnu, CTLFLAG_RD, &seminfo.semmnu, 0, ""); 144SYSCTL_INT(_kern_ipc, OID_AUTO, semmsl, CTLFLAG_RW, &seminfo.semmsl, 0, ""); 145SYSCTL_INT(_kern_ipc, OID_AUTO, semopm, CTLFLAG_RD, &seminfo.semopm, 0, ""); 146SYSCTL_INT(_kern_ipc, OID_AUTO, semume, CTLFLAG_RD, &seminfo.semume, 0, ""); 147SYSCTL_INT(_kern_ipc, OID_AUTO, semusz, CTLFLAG_RD, &seminfo.semusz, 0, ""); 148SYSCTL_INT(_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RW, &seminfo.semvmx, 0, ""); 149SYSCTL_INT(_kern_ipc, OID_AUTO, semaem, CTLFLAG_RW, &seminfo.semaem, 0, ""); 150 151#if 0 152RO seminfo.semmap /* SEMMAP unused */ 153RO seminfo.semmni 154RO seminfo.semmns 155RO seminfo.semmnu /* undo entries per system */ 156RW seminfo.semmsl 157RO seminfo.semopm /* SEMOPM unused */ 158RO seminfo.semume 159RO seminfo.semusz /* param - derived from SEMUME for per-proc sizeof */ 160RO seminfo.semvmx /* SEMVMX unused - user param */ 161RO seminfo.semaem /* SEMAEM unused - user param */ 162#endif 163 164static void |
49seminit(dummy) 50 void *dummy; 51{ 52 register int i; 53 | 165seminit(dummy) 166 void *dummy; 167{ 168 register int i; 169 |
170 sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK); 171 if (sem == NULL) 172 panic("sem is NULL"); 173 sema = malloc(sizeof(struct semid_ds) * seminfo.semmni, M_SEM, M_WAITOK); |
|
54 if (sema == NULL) 55 panic("sema is NULL"); | 174 if (sema == NULL) 175 panic("sema is NULL"); |
176 semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK); |
|
56 if (semu == NULL) 57 panic("semu is NULL"); 58 59 for (i = 0; i < seminfo.semmni; i++) { 60 sema[i].sem_base = 0; 61 sema[i].sem_perm.mode = 0; 62 } 63 for (i = 0; i < seminfo.semmnu; i++) { 64 register struct sem_undo *suptr = SEMU(i); 65 suptr->un_proc = NULL; 66 } 67 semu_list = NULL; 68} | 177 if (semu == NULL) 178 panic("semu is NULL"); 179 180 for (i = 0; i < seminfo.semmni; i++) { 181 sema[i].sem_base = 0; 182 sema[i].sem_perm.mode = 0; 183 } 184 for (i = 0; i < seminfo.semmnu; i++) { 185 register struct sem_undo *suptr = SEMU(i); 186 suptr->un_proc = NULL; 187 } 188 semu_list = NULL; 189} |
190SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) |
|
69 70/* 71 * Entry point for all SEM calls 72 */ 73int 74semsys(p, uap) 75 struct proc *p; 76 /* XXX actually varargs. */ --- 626 unchanged lines hidden (view full) --- 703#ifdef SEM_DEBUG 704 printf("semop: good morning!\n"); 705#endif 706 707 /* 708 * Make sure that the semaphore still exists 709 */ 710 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || | 191 192/* 193 * Entry point for all SEM calls 194 */ 195int 196semsys(p, uap) 197 struct proc *p; 198 /* XXX actually varargs. */ --- 626 unchanged lines hidden (view full) --- 825#ifdef SEM_DEBUG 826 printf("semop: good morning!\n"); 827#endif 828 829 /* 830 * Make sure that the semaphore still exists 831 */ 832 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || |
711 semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { 712 /* The man page says to return EIDRM. */ 713 /* Unfortunately, BSD doesn't define that code! */ 714#ifdef EIDRM | 833 semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) |
715 return(EIDRM); | 834 return(EIDRM); |
716#else 717 return(EINVAL); 718#endif 719 } | |
720 721 /* 722 * The semaphore is still alive. Readjust the count of 723 * waiting processes. 724 */ 725 if (sopptr->sem_op == 0) 726 semptr->semzcnt--; 727 else --- 164 unchanged lines hidden --- | 835 836 /* 837 * The semaphore is still alive. Readjust the count of 838 * waiting processes. 839 */ 840 if (sopptr->sem_op == 0) 841 semptr->semzcnt--; 842 else --- 164 unchanged lines hidden --- |