summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2002-05-05 00:03:29 +0000
committerTom Lane2002-05-05 00:03:29 +0000
commit72a3902a664c7fbceb2034e28e444b28f96fa717 (patch)
treeff42e4494af6ea1c1cdf524f3feb5fc670217f0c /src/include
parent91fc10fdacfcbadc123fd9d8ee16a4568f8c636b (diff)
Create an internal semaphore API that is not tied to SysV semaphores.
As proof of concept, provide an alternate implementation based on POSIX semaphores. Also push the SysV shared-memory implementation into a separate file so that it can be replaced conveniently.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/miscadmin.h9
-rw-r--r--src/include/pg_config.h.in11
-rw-r--r--src/include/storage/ipc.h71
-rw-r--r--src/include/storage/pg_sema.h76
-rw-r--r--src/include/storage/pg_shmem.h44
-rw-r--r--src/include/storage/proc.h49
-rw-r--r--src/include/storage/s_lock.h15
-rw-r--r--src/include/storage/spin.h4
8 files changed, 152 insertions, 127 deletions
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 99f7fae88bf..09e1c0fe635 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: miscadmin.h,v 1.102 2002/04/04 04:25:51 momjian Exp $
+ * $Id: miscadmin.h,v 1.103 2002/05/05 00:03:29 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to
@@ -23,7 +23,8 @@
#ifndef MISCADMIN_H
#define MISCADMIN_H
-#include "storage/ipc.h"
+#include <sys/types.h>
+
/*****************************************************************************
* System interrupt and critical section handling
@@ -291,8 +292,8 @@ extern void BaseInit(void);
extern bool CreateDataDirLockFile(const char *datadir, bool amPostmaster);
extern bool CreateSocketLockFile(const char *socketfile, bool amPostmaster);
extern void TouchSocketLockFile(void);
-extern void RecordSharedMemoryInLockFile(IpcMemoryKey shmKey,
- IpcMemoryId shmId);
+extern void RecordSharedMemoryInLockFile(unsigned long id1,
+ unsigned long id2);
extern void ValidatePgVersion(const char *path);
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 80b904181d3..b3a5b8d6e1b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -8,7 +8,7 @@
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
* changes will be overwritten the next time you run configure.
*
- * $Id: pg_config.h.in,v 1.23 2002/04/21 19:48:19 thomas Exp $
+ * $Id: pg_config.h.in,v 1.24 2002/05/05 00:03:29 tgl Exp $
*/
#ifndef PG_CONFIG_H
@@ -711,6 +711,15 @@ extern int fdatasync(int fildes);
/* Define if you have syslog() */
#undef HAVE_SYSLOG
+/* Define exactly one of these symbols to select semaphore implementation */
+#undef USE_NAMED_POSIX_SEMAPHORES
+#undef USE_UNNAMED_POSIX_SEMAPHORES
+#undef USE_SYSV_SEMAPHORES
+
+/* Define exactly one of these symbols to select shared-mem implementation */
+#undef USE_SYSV_SHARED_MEMORY
+
+
/*
*------------------------------------------------------------------------
* Part 4: pull in system-specific declarations.
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 6a96ea2d125..5ebee36b9f7 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -3,63 +3,21 @@
* ipc.h
* POSTGRES inter-process communication definitions.
*
+ * This file is misnamed, as it no longer has much of anything directly
+ * to do with IPC. The functionality here is concerned with managing
+ * exit-time cleanup for either a postmaster or a backend.
+ *
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: ipc.h,v 1.54 2001/11/05 17:46:35 momjian Exp $
+ * $Id: ipc.h,v 1.55 2002/05/05 00:03:29 tgl Exp $
*
- * Some files that would normally need to include only sys/ipc.h must
- * instead include this file because on Ultrix, sys/ipc.h is not designed
- * to be included multiple times. This file (by virtue of the ifndef IPC_H)
- * is.
*-------------------------------------------------------------------------
*/
#ifndef IPC_H
#define IPC_H
-#include <sys/types.h>
-#ifdef HAVE_SYS_IPC_H
-#include <sys/ipc.h>
-#endif /* HAVE_SYS_IPC_H */
-
-#ifndef HAVE_UNION_SEMUN
-union semun
-{
- int val;
- struct semid_ds *buf;
- unsigned short *array;
-};
-#endif
-
-
-/* generic IPC definitions */
-
-#define IPCProtection (0600) /* access/modify by user only */
-
-/* semaphore definitions */
-
-typedef uint32 IpcSemaphoreKey; /* semaphore key passed to semget(2) */
-typedef int IpcSemaphoreId; /* semaphore ID returned by semget(2) */
-
-#define IPC_NMAXSEM 32 /* maximum number of semaphores per semID */
-
-#define PGSemaMagic 537 /* must be less than SEMVMX */
-
-/* shared memory definitions */
-
-typedef uint32 IpcMemoryKey; /* shared memory key passed to shmget(2) */
-typedef int IpcMemoryId; /* shared memory ID returned by shmget(2) */
-
-typedef struct PGShmemHeader /* standard header for all Postgres shmem */
-{
- int32 magic; /* magic # to identify Postgres segments */
-#define PGShmemMagic 679834892
- pid_t creatorPID; /* PID of creating process */
- uint32 totalsize; /* total size of segment */
- uint32 freeoffset; /* offset to first free space */
-} PGShmemHeader;
-
/* ipc.c */
extern bool proc_exit_inprogress;
@@ -70,24 +28,9 @@ extern void on_proc_exit(void (*function) (), Datum arg);
extern void on_shmem_exit(void (*function) (), Datum arg);
extern void on_exit_reset(void);
-extern void IpcInitKeyAssignment(int port);
-
-extern IpcSemaphoreId IpcSemaphoreCreate(int numSems, int permission,
- int semStartValue,
- bool removeOnExit);
-extern void IpcSemaphoreKill(IpcSemaphoreId semId);
-extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, bool interruptOK);
-extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem);
-extern bool IpcSemaphoreTryLock(IpcSemaphoreId semId, int sem);
-extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem);
-
-extern PGShmemHeader *IpcMemoryCreate(uint32 size, bool makePrivate,
- int permission);
-
-extern bool SharedMemoryIsInUse(IpcMemoryKey shmKey, IpcMemoryId shmId);
-
/* ipci.c */
extern void CreateSharedMemoryAndSemaphores(bool makePrivate,
- int maxBackends);
+ int maxBackends,
+ int port);
#endif /* IPC_H */
diff --git a/src/include/storage/pg_sema.h b/src/include/storage/pg_sema.h
new file mode 100644
index 00000000000..65c1936c29f
--- /dev/null
+++ b/src/include/storage/pg_sema.h
@@ -0,0 +1,76 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_sema.h
+ * Platform-independent API for semaphores.
+ *
+ * PostgreSQL requires counting semaphores (the kind that keep track of
+ * multiple unlock operations, and will allow an equal number of subsequent
+ * lock operations before blocking). The underlying implementation is
+ * not the same on every platform. This file defines the API that must
+ * be provided by each port.
+ *
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: pg_sema.h,v 1.1 2002/05/05 00:03:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_SEMA_H
+#define PG_SEMA_H
+
+/*
+ * PGSemaphoreData and pointer type PGSemaphore are the data structure
+ * representing an individual semaphore. The contents of PGSemaphoreData
+ * vary across implementations and must never be touched by platform-
+ * independent code. PGSemaphoreData structures are always allocated
+ * in shared memory (to support implementations where the data changes during
+ * lock/unlock).
+ *
+ * pg_config.h must define exactly one of the USE_xxx_SEMAPHORES symbols.
+ */
+
+#ifdef USE_NAMED_POSIX_SEMAPHORES
+
+#include <semaphore.h>
+
+typedef sem_t *PGSemaphoreData;
+
+#endif
+
+#ifdef USE_UNNAMED_POSIX_SEMAPHORES
+
+#include <semaphore.h>
+
+typedef sem_t PGSemaphoreData;
+
+#endif
+
+#ifdef USE_SYSV_SEMAPHORES
+
+typedef struct PGSemaphoreData
+{
+ int semId; /* semaphore set identifier */
+ int semNum; /* semaphore number within set */
+} PGSemaphoreData;
+
+#endif
+
+typedef PGSemaphoreData *PGSemaphore;
+
+
+/* Module initialization (called during postmaster start or shmem reinit) */
+extern void PGReserveSemaphores(int maxSemas, int port);
+/* Initialize a PGSemaphore structure to represent a sema with count 1 */
+extern void PGSemaphoreCreate(PGSemaphore sema);
+/* Reset a previously-initialized PGSemaphore to have count 0 */
+extern void PGSemaphoreReset(PGSemaphore sema);
+/* Lock a semaphore (decrement count), blocking if count would be < 0 */
+extern void PGSemaphoreLock(PGSemaphore sema, bool interruptOK);
+/* Unlock a semaphore (increment count) */
+extern void PGSemaphoreUnlock(PGSemaphore sema);
+/* Lock a semaphore only if able to do so without blocking */
+extern bool PGSemaphoreTryLock(PGSemaphore sema);
+
+#endif /* PG_SEMA_H */
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
new file mode 100644
index 00000000000..fa35e63f725
--- /dev/null
+++ b/src/include/storage/pg_shmem.h
@@ -0,0 +1,44 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_shmem.h
+ * Platform-independent API for shared memory support.
+ *
+ * Every port is expected to support shared memory with approximately
+ * SysV-ish semantics; in particular, a memory block is not anonymous
+ * but has an ID, and we must be able to tell whether there are any
+ * remaining processes attached to a block of a specified ID.
+ *
+ * To simplify life for the SysV implementation, the ID is assumed to
+ * consist of two unsigned long values (these are key and ID in SysV
+ * terms). Other platforms may ignore the second value if they need
+ * only one ID number.
+ *
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: pg_shmem.h,v 1.1 2002/05/05 00:03:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_SHMEM_H
+#define PG_SHMEM_H
+
+#include <sys/types.h>
+
+
+typedef struct PGShmemHeader /* standard header for all Postgres shmem */
+{
+ int32 magic; /* magic # to identify Postgres segments */
+#define PGShmemMagic 679834892
+ pid_t creatorPID; /* PID of creating process */
+ uint32 totalsize; /* total size of segment */
+ uint32 freeoffset; /* offset to first free space */
+} PGShmemHeader;
+
+
+extern PGShmemHeader *PGSharedMemoryCreate(uint32 size, bool makePrivate,
+ int port);
+extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2);
+
+#endif /* PG_SHMEM_H */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index e1700b23727..e276fddf9cd 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: proc.h,v 1.54 2001/11/06 00:38:26 tgl Exp $
+ * $Id: proc.h,v 1.55 2002/05/05 00:03:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,16 +16,10 @@
#include "access/xlog.h"
#include "storage/backendid.h"
-#include "storage/ipc.h"
#include "storage/lock.h"
+#include "storage/pg_sema.h"
-typedef struct
-{
- IpcSemaphoreId semId; /* SysV semaphore set ID */
- int semNum; /* semaphore number within set */
-} SEMA;
-
/*
* Each backend has a PROC struct in shared memory. There is also a list of
* currently-unused PROC structs that will be reallocated to new backends.
@@ -39,7 +33,7 @@ struct PROC
/* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */
SHM_QUEUE links; /* list link if process is in a list */
- SEMA sem; /* ONE semaphore to sleep on */
+ PGSemaphoreData sem; /* ONE semaphore to sleep on */
int errType; /* STATUS_OK or STATUS_ERROR after wakeup */
TransactionId xid; /* transaction currently being executed by
@@ -84,47 +78,11 @@ extern PROC *MyProc;
/*
* There is one ProcGlobal struct for the whole installation.
- *
- * PROC_NSEMS_PER_SET is the number of semaphores in each sys-V semaphore set
- * we allocate. It must be no more than 32 (or however many bits in an int
- * on your machine), or our free-semaphores bitmap won't work. It also must
- * be *less than* your kernel's SEMMSL (max semaphores per set) parameter,
- * which is often around 25. (Less than, because we allocate one extra sema
- * in each set for identification purposes.)
- *
- * PROC_SEM_MAP_ENTRIES is the number of semaphore sets we need to allocate
- * to keep track of up to maxBackends backends. Note that we need one extra
- * semaphore (see storage/lmgr/proc.c), so the computation may look wrong,
- * but it's right.
*/
-#define PROC_NSEMS_PER_SET 16
-#define PROC_SEM_MAP_ENTRIES(maxBackends) ((maxBackends)/PROC_NSEMS_PER_SET+1)
-
-typedef struct
-{
- /* info about a single set of per-process semaphores */
- IpcSemaphoreId procSemId;
- int32 freeSemMap;
-
- /*
- * In freeSemMap, bit i is set if the i'th semaphore of this sema set
- * is allocated to a process. (i counts from 0 at the LSB)
- */
-} SEM_MAP_ENTRY;
-
typedef struct PROC_HDR
{
/* Head of list of free PROC structures */
SHMEM_OFFSET freeProcs;
-
- /* Info about semaphore sets used for per-process semaphores */
- int semMapEntries;
-
- /*
- * VARIABLE LENGTH ARRAY: actual length is semMapEntries. THIS MUST BE
- * LAST IN THE STRUCT DECLARATION.
- */
- SEM_MAP_ENTRY procSemMap[1];
} PROC_HDR;
@@ -135,6 +93,7 @@ extern int DeadlockTimeout;
/*
* Function Prototypes
*/
+extern int ProcGlobalSemas(int maxBackends);
extern void InitProcGlobal(int maxBackends);
extern void InitProcess(void);
extern void InitDummyProcess(void);
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index be79b51a17b..41a79102d78 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -63,14 +63,14 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: s_lock.h,v 1.97 2002/01/29 15:44:42 tgl Exp $
+ * $Id: s_lock.h,v 1.98 2002/05/05 00:03:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef S_LOCK_H
#define S_LOCK_H
-#include "storage/ipc.h"
+#include "storage/pg_sema.h"
#if defined(HAS_TEST_AND_SET)
@@ -438,7 +438,6 @@ extern slock_t wc_tas(volatile slock_t *lock);
* AIX (POWER)
*
* Note that slock_t on POWER/POWER2/PowerPC is int instead of char
- * (see storage/ipc.h).
*/
#define TAS(lock) cs((int *) (lock), 0, 1)
#endif /* _AIX */
@@ -462,17 +461,11 @@ extern slock_t wc_tas(volatile slock_t *lock);
#else /* !HAS_TEST_AND_SET */
/*
- * Fake spinlock implementation using SysV semaphores --- slow and prone
+ * Fake spinlock implementation using semaphores --- slow and prone
* to fall foul of kernel limits on number of semaphores, so don't use this
* unless you must! The subroutines appear in spin.c.
*/
-
-typedef struct
-{
- /* reference to semaphore used to implement this spinlock */
- IpcSemaphoreId semId;
- int sem;
-} slock_t;
+typedef PGSemaphoreData slock_t;
extern bool s_lock_free_sema(volatile slock_t *lock);
extern void s_unlock_sema(volatile slock_t *lock);
diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h
index 6ec0552ca64..8279af0efb0 100644
--- a/src/include/storage/spin.h
+++ b/src/include/storage/spin.h
@@ -40,7 +40,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: spin.h,v 1.19 2001/11/05 17:46:35 momjian Exp $
+ * $Id: spin.h,v 1.20 2002/05/05 00:03:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -72,6 +72,6 @@
#define SpinLockFree(lock) S_LOCK_FREE(lock)
-extern void CreateSpinlocks(void);
+extern int SpinlockSemas(void);
#endif /* SPIN_H */