1010 * - this required changing sem_info from containig an array of sem_t to an array of sem_t*
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.3 2001/03/22 03:59:42 momjian Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.4 2001/09/07 00:27:29 tgl Exp $
1414 *
1515 *-------------------------------------------------------------------------
1616 */
17+ #include "postgres.h"
1718
1819#include <errno.h>
1920#include <semaphore.h>
2223#include <unistd.h>
2324#include <fcntl.h>
2425#include <sys/mman.h>
25- #include "postgres.h"
26+
27+ #include "miscadmin.h"
2628#include "storage/ipc.h"
2729#include "storage/proc.h"
2830#include "port/darwin/sem.h"
2931
3032#define SEMMAX IPC_NMAXSEM
31- #define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX)
3233#define OPMAX 8
3334
3435#define MODE 0700
@@ -41,19 +42,23 @@ struct pending_ops
4142int idx ;/* index of first free array member */
4243};
4344
45+ struct sem_set_info
46+ {
47+ key_t key ;
48+ int nsems ;
49+ sem_t * sem [SEMMAX ];/* array of POSIX semaphores */
50+ struct sem semV [SEMMAX ];/* array of System V semaphore
51+ * structures */
52+ struct pending_ops pendingOps [SEMMAX ];/* array of pending
53+ * operations */
54+ };
55+
4456struct sem_info
4557{
4658sem_t * sem ;
47- struct
48- {
49- key_t key ;
50- int nsems ;
51- sem_t * sem [SEMMAX ];/* array of POSIX semaphores */
52- struct sem semV [SEMMAX ];/* array of System V semaphore
53- * structures */
54- struct pending_ops pendingOps [SEMMAX ];/* array of pending
55- * operations */
56- }set [SETMAX ];
59+ int nsets ;
60+ /* there are actually nsets of these: */
61+ struct sem_set_info set [1 ];/* VARIABLE LENGTH ARRAY */
5762};
5863
5964static struct sem_info * SemInfo = (struct sem_info * )- 1 ;
@@ -66,7 +71,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
6671
6772sem_wait (SemInfo -> sem );
6873
69- if (semid < 0 || semid >=SETMAX ||
74+ if (semid < 0 || semid >=SemInfo -> nsets ||
7075semnum < 0 || semnum >=SemInfo -> set [semid ].nsems )
7176{
7277sem_post (SemInfo -> sem );
@@ -132,8 +137,10 @@ semget(key_t key, int nsems, int semflg)
132137{
133138int fd ,
134139semid ,
135- semnum /* , semnum1 */ ;
140+ semnum ,
141+ nsets ;
136142int exist = 0 ;
143+ Size sem_info_size ;
137144char semname [64 ];
138145
139146if (nsems < 0 || nsems > SEMMAX )
@@ -163,44 +170,46 @@ semget(key_t key, int nsems, int semflg)
163170return fd ;
164171shm_unlink (SHM_INFO_NAME );
165172/* The size may only be set once. Ignore errors. */
166- ftruncate (fd ,sizeof (struct sem_info ));
167- SemInfo = mmap (NULL ,sizeof (struct sem_info ),
173+ nsets = PROC_SEM_MAP_ENTRIES (MaxBackends );
174+ sem_info_size = sizeof (struct sem_info )+ (nsets - 1 )* sizeof (struct sem_set_info );
175+ ftruncate (fd ,sem_info_size );
176+ SemInfo = mmap (NULL ,sem_info_size ,
168177PROT_READ |PROT_WRITE ,MAP_SHARED ,fd ,0 );
169178if (SemInfo == MAP_FAILED )
170179return -1 ;
171180if (!exist )
172181{
182+ /* initialize shared memory */
183+ memset (SemInfo ,0 ,sem_info_size );
184+ SemInfo -> nsets = nsets ;
185+ for (semid = 0 ;semid < nsets ;semid ++ )
186+ SemInfo -> set [semid ].key = -1 ;
173187/* create semaphore for locking */
174188sprintf (semname ,"%s-map" ,SEM_NAME );
175189#ifdef DEBUG_IPC
176190fprintf (stderr ,"darwin creating sem %s to cover shared mem.\n" ,semname );
177191#endif
178192SemInfo -> sem = sem_open (semname ,O_CREAT ,semflg & 0777 ,1 );
179193sem_unlink (semname );
180- sem_wait (SemInfo -> sem );
181- /* initilize shared memory */
182- memset (SemInfo -> set ,0 ,sizeof (SemInfo -> set ));
183- for (semid = 0 ;semid < SETMAX ;semid ++ )
184- SemInfo -> set [semid ].key = -1 ;
185- sem_post (SemInfo -> sem );
186194}
187195}
188196
189197sem_wait (SemInfo -> sem );
198+ nsets = SemInfo -> nsets ;
190199
191200if (key != IPC_PRIVATE )
192201{
193202/* search existing element */
194203semid = 0 ;
195- while (semid < SETMAX && SemInfo -> set [semid ].key != key )
204+ while (semid < nsets && SemInfo -> set [semid ].key != key )
196205semid ++ ;
197- if (!(semflg & IPC_CREAT )&& semid >=SETMAX )
206+ if (!(semflg & IPC_CREAT )&& semid >=nsets )
198207{
199208sem_post (SemInfo -> sem );
200209errno = ENOENT ;
201210return -1 ;
202211}
203- else if (semid < SETMAX )
212+ else if (semid < nsets )
204213{
205214if (semflg & IPC_CREAT && semflg & IPC_EXCL )
206215{
@@ -228,12 +237,12 @@ semget(key_t key, int nsems, int semflg)
228237
229238/* search first free element */
230239semid = 0 ;
231- while (semid < SETMAX && SemInfo -> set [semid ].key != -1 )
240+ while (semid < nsets && SemInfo -> set [semid ].key != -1 )
232241semid ++ ;
233- if (semid >=SETMAX )
242+ if (semid >=nsets )
234243{
235244#ifdef DEBUG_IPC
236- fprintf (stderr ,"darwin semget failed because all keys were -1 up to SETMAX \n" );
245+ fprintf (stderr ,"darwin semget failed because all keys were -1\n" );
237246#endif
238247sem_post (SemInfo -> sem );
239248errno = ENOSPC ;
@@ -249,15 +258,18 @@ semget(key_t key, int nsems, int semflg)
249258SemInfo -> set [semid ].sem [semnum ]= sem_open (semname ,O_CREAT ,semflg & 0777 ,0 );
250259sem_unlink (semname );
251260
252- /* Currently sem_init always returns -1.
253- if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ){
254- for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
255- sem_close( SemInfo->set[semid].sem[semnum1] );
256- }
257- sem_post( SemInfo->sem );
258- return -1;
259- }
260- */
261+ /* Currently sem_init always returns -1. */
262+ #ifdef NOT_USED
263+ if (sem_init (& SemInfo -> set [semid ].sem [semnum ],1 ,0 )== -1 ){
264+ int semnum1 ;
265+
266+ for (semnum1 = 0 ;semnum1 < semnum ;semnum1 ++ ) {
267+ sem_close (SemInfo -> set [semid ].sem [semnum1 ] );
268+ }
269+ sem_post (SemInfo -> sem );
270+ return -1 ;
271+ }
272+ #endif
261273}
262274
263275SemInfo -> set [semid ].key = key ;
@@ -279,7 +291,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
279291
280292sem_wait (SemInfo -> sem );
281293
282- if (semid < 0 || semid >=SETMAX )
294+ if (semid < 0 || semid >=SemInfo -> nsets )
283295{
284296sem_post (SemInfo -> sem );
285297errno = EINVAL ;