From 8df5625966bce3a43d3a9a58654a673a8e13d0e6 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 5 May 2002 01:03:26 +0000 Subject: [PATCH] First test of Darwin port with POSIX semaphore code. --- src/backend/port/darwin/Makefile | 4 +- src/backend/port/darwin/README | 16 +- src/backend/port/darwin/sem.c | 389 ------------------------------- src/backend/port/posix_sema.c | 6 +- 4 files changed, 8 insertions(+), 407 deletions(-) delete mode 100644 src/backend/port/darwin/sem.c diff --git a/src/backend/port/darwin/Makefile b/src/backend/port/darwin/Makefile index 898fb627e3..2c72ab31d3 100644 --- a/src/backend/port/darwin/Makefile +++ b/src/backend/port/darwin/Makefile @@ -4,7 +4,7 @@ # Makefile for port/darwin # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/port/darwin/Makefile,v 1.2 2001/11/08 04:24:03 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/port/darwin/Makefile,v 1.3 2002/05/05 01:03:26 tgl Exp $ # #------------------------------------------------------------------------- @@ -12,7 +12,7 @@ subdir = src/backend/port/darwin top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = sem.o system.o +OBJS = system.o all: SUBSYS.o diff --git a/src/backend/port/darwin/README b/src/backend/port/darwin/README index 1a056bd514..1c160654a4 100644 --- a/src/backend/port/darwin/README +++ b/src/backend/port/darwin/README @@ -16,23 +16,11 @@ Radar Bug#s 2767956, 2683531, 2805147. One hopes we can retire this kluge in the not too distant future. -As of PostgreSQL 7.2 and Mac OS X 10.1, one should expect warnings +As of PostgreSQL 7.3 and Mac OS X 10.1, one should expect warnings like these while linking the backend: /usr/bin/ld: warning unused multiple definitions of symbol _system port/SUBSYS.o definition of _system in section (__TEXT,__text) /usr/lib/libm.dylib(system.o) unused definition of _system -/usr/bin/ld: warning unused multiple definitions of symbol _semctl -port/SUBSYS.o definition of _semctl in section (__TEXT,__text) -/usr/lib/libm.dylib(semctl.o) unused definition of _semctl -/usr/bin/ld: warning unused multiple definitions of symbol _semget -port/SUBSYS.o definition of _semget in section (__TEXT,__text) -/usr/lib/libm.dylib(semget.o) unused definition of _semget -/usr/bin/ld: warning unused multiple definitions of symbol _semop -port/SUBSYS.o definition of _semop in section (__TEXT,__text) -/usr/lib/libm.dylib(semop.o) unused definition of _semop -The first of these shows us overriding system() per the above-described -hack. The rest show sem.c overriding the nonfunctional semaphore stubs -in libc. (Perhaps sem.c can also be retired someday, but semget support -is reportedly not high on Apple's to-do list.) +These are due to overriding system() per the above-described hack. diff --git a/src/backend/port/darwin/sem.c b/src/backend/port/darwin/sem.c deleted file mode 100644 index abb52c0b90..0000000000 --- a/src/backend/port/darwin/sem.c +++ /dev/null @@ -1,389 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sem.c - * System V Semaphore Emulation - * - * Copyright (c) 1999, repas AEG Automation GmbH - * - * 2000-12-1 pmb@mac.com - * - changed from anonymous to named semaphores for darwin - * - this required changing sem_info from containig an array of sem_t to an array of sem_t* - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.5 2001/10/25 05:49:40 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "miscadmin.h" -#include "storage/ipc.h" -#include "storage/proc.h" -#include "port/darwin/sem.h" - -#define SEMMAX IPC_NMAXSEM -#define OPMAX 8 - -#define MODE 0700 -#define SHM_INFO_NAME "SysV_Sem_Info" -#define SEM_NAME "/pgsql-darwin" - -struct pending_ops -{ - int op[OPMAX]; /* array of pending operations */ - int idx; /* index of first free array member */ -}; - -struct sem_set_info -{ - key_t key; - int nsems; - sem_t *sem[SEMMAX]; /* array of POSIX semaphores */ - struct sem semV[SEMMAX]; /* array of System V semaphore structures */ - struct pending_ops pendingOps[SEMMAX]; /* array of pending - * operations */ -}; - -struct sem_info -{ - sem_t *sem; - int nsets; - /* there are actually nsets of these: */ - struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */ -}; - -static struct sem_info *SemInfo = (struct sem_info *) - 1; - - -int -semctl(int semid, int semnum, int cmd, /* ... */ union semun arg) -{ - int r = 0; - - sem_wait(SemInfo->sem); - - if (semid < 0 || semid >= SemInfo->nsets || - semnum < 0 || semnum >= SemInfo->set[semid].nsems) - { - sem_post(SemInfo->sem); - errno = EINVAL; - return -1; - } - - switch (cmd) - { - case GETNCNT: - r = SemInfo->set[semid].semV[semnum].semncnt; - break; - - case GETPID: - r = SemInfo->set[semid].semV[semnum].sempid; - break; - - case GETVAL: - r = SemInfo->set[semid].semV[semnum].semval; - break; - - case GETALL: - for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++) - arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval; - break; - - case SETVAL: - SemInfo->set[semid].semV[semnum].semval = arg.val; - break; - - case SETALL: - for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++) - SemInfo->set[semid].semV[semnum].semval = arg.array[semnum]; - break; - - case GETZCNT: - r = SemInfo->set[semid].semV[semnum].semzcnt; - break; - - case IPC_RMID: - for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++) - { - if (sem_close(SemInfo->set[semid].sem[semnum]) == -1) - r = -1; - } - SemInfo->set[semid].key = -1; - SemInfo->set[semid].nsems = 0; - break; - - default: - sem_post(SemInfo->sem); - errno = EINVAL; - return -1; - } - - sem_post(SemInfo->sem); - - return r; -} - -int -semget(key_t key, int nsems, int semflg) -{ - int fd, - semid, - semnum, - nsets; - int exist = 0; - Size sem_info_size; - char semname[64]; - - if (nsems < 0 || nsems > SEMMAX) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget aborting because nsems out of range. (%d)\n", nsems); -#endif - errno = EINVAL; - return -1; - } - - /* open and map shared memory */ - if (SemInfo == (struct sem_info *) - 1) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin initializing shared mem for semaphore shim.\n"); -#endif - /* test if the shared memory already exists */ - fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE); - if (fd == -1 && errno == EEXIST) - { -/* exist = 1; */ - shm_unlink(SHM_INFO_NAME); - fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE); - } - if (fd == -1) - return fd; - shm_unlink(SHM_INFO_NAME); - /* The size may only be set once. Ignore errors. */ - nsets = PROC_SEM_MAP_ENTRIES(MaxBackends); - sem_info_size = sizeof(struct sem_info) + (nsets - 1) * sizeof(struct sem_set_info); - ftruncate(fd, sem_info_size); - SemInfo = mmap(NULL, sem_info_size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (SemInfo == MAP_FAILED) - return -1; - if (!exist) - { - /* initialize shared memory */ - memset(SemInfo, 0, sem_info_size); - SemInfo->nsets = nsets; - for (semid = 0; semid < nsets; semid++) - SemInfo->set[semid].key = -1; - /* create semaphore for locking */ - sprintf(semname, "%s-map", SEM_NAME); -#ifdef DEBUG_IPC - fprintf(stderr, "darwin creating sem %s to cover shared mem.\n", semname); -#endif - SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1); - sem_unlink(semname); - } - } - - sem_wait(SemInfo->sem); - nsets = SemInfo->nsets; - - if (key != IPC_PRIVATE) - { - /* search existing element */ - semid = 0; - while (semid < nsets && SemInfo->set[semid].key != key) - semid++; - if (!(semflg & IPC_CREAT) && semid >= nsets) - { - sem_post(SemInfo->sem); - errno = ENOENT; - return -1; - } - else if (semid < nsets) - { - if (semflg & IPC_CREAT && semflg & IPC_EXCL) - { - sem_post(SemInfo->sem); - errno = EEXIST; - return -1; - } - else - { - if (nsems != 0 && SemInfo->set[semid].nsems < nsems) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget failed because if (nsems != 0 && SemInfo->set[semid].nsems < nsems) %d %d\n", - nsems, SemInfo->set[semid].nsems); -#endif - sem_post(SemInfo->sem); - errno = EINVAL; - return -1; - } - sem_post(SemInfo->sem); - return semid; - } - } - } - - /* search first free element */ - semid = 0; - while (semid < nsets && SemInfo->set[semid].key != -1) - semid++; - if (semid >= nsets) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget failed because all keys were -1\n"); -#endif - sem_post(SemInfo->sem); - errno = ENOSPC; - return -1; - } - - for (semnum = 0; semnum < nsems; semnum++) - { - sprintf(semname, "%s-%d-%d", SEM_NAME, semid, semnum); -#ifdef DEBUG_IPC - fprintf(stderr, "darwin creating sem %s to cover set %d num %dm.\n", semname, semid, semnum); -#endif - SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0); - sem_unlink(semname); - - /* Currently sem_init always returns -1. */ -#ifdef NOT_USED - if (sem_init(&SemInfo->set[semid].sem[semnum], 1, 0) == -1) - { - int semnum1; - - for (semnum1 = 0; semnum1 < semnum; semnum1++) - sem_close(SemInfo->set[semid].sem[semnum1]); - sem_post(SemInfo->sem); - return -1; - } -#endif - } - - SemInfo->set[semid].key = key; - SemInfo->set[semid].nsems = nsems; - - sem_post(SemInfo->sem); - - return semid; -} - -int -semop(int semid, struct sembuf * sops, size_t nsops) -{ - int i, - r = 0, - r1, - errno1 = 0, - op; - - sem_wait(SemInfo->sem); - - if (semid < 0 || semid >= SemInfo->nsets) - { - sem_post(SemInfo->sem); - errno = EINVAL; - return -1; - } - for (i = 0; i < nsops; i++) - { - if ( /* sops[i].sem_num < 0 || */ sops[i].sem_num >= SemInfo->set[semid].nsems) - { - sem_post(SemInfo->sem); - errno = EFBIG; - return -1; - } - } - - for (i = 0; i < nsops; i++) - { - if (sops[i].sem_op < 0) - { - if (SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op) - { - if (sops[i].sem_flg & IPC_NOWAIT) - { - sem_post(SemInfo->sem); - errno = EAGAIN; - return -1; - } - SemInfo->set[semid].semV[sops[i].sem_num].semncnt++; - if (SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX) - { - /* pending operations array overflow */ - sem_post(SemInfo->sem); - errno = ERANGE; - return -1; - } - SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op; - /* suspend */ - sem_post(SemInfo->sem); /* avoid deadlock */ - r1 = sem_wait(SemInfo->set[semid].sem[sops[i].sem_num]); - sem_wait(SemInfo->sem); - if (r1) - { - errno1 = errno; - r = r1; - /* remove pending operation */ - SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0; - } - else - SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op; - SemInfo->set[semid].semV[sops[i].sem_num].semncnt--; - } - else - SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op; - } - else if (sops[i].sem_op > 0) - { - SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op; - op = sops[i].sem_op; - while (op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0) - { /* operations pending */ - if (SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] + op >= 0) - { - /* unsuspend processes */ - if (sem_post(SemInfo->set[semid].sem[sops[i].sem_num])) - { - errno1 = errno; - r = -1; - } - /* adjust pending operations */ - op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx]; - SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0; - } - else - { - /* adjust pending operations */ - SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] += op; - op = 0; - } - } - } - else - /* sops[i].sem_op == 0 */ - { - /* not supported */ - sem_post(SemInfo->sem); - errno = ENOSYS; - return -1; - } - SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid(); - } - - sem_post(SemInfo->sem); - - errno = errno1; - return r; -} diff --git a/src/backend/port/posix_sema.c b/src/backend/port/posix_sema.c index 1dd02f8def..2c32421e8d 100644 --- a/src/backend/port/posix_sema.c +++ b/src/backend/port/posix_sema.c @@ -11,7 +11,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/port/posix_sema.c,v 1.1 2002/05/05 00:03:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/port/posix_sema.c,v 1.2 2002/05/05 01:03:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,8 @@ #include #include +#include "miscadmin.h" +#include "storage/ipc.h" #include "storage/pg_sema.h" @@ -70,7 +72,7 @@ PosixSemaphoreCreate(void) mySem = sem_open(semname, O_CREAT | O_EXCL, (mode_t) IPCProtection, (unsigned) 1); - if (mySem != SEM_FAILED) + if (mySem != (sem_t *) SEM_FAILED) break; /* Loop if error indicates a collision */ -- 2.40.0