diff options
Diffstat (limited to 'src/backend/storage/ipc.h')
-rw-r--r-- | src/backend/storage/ipc.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/src/backend/storage/ipc.h b/src/backend/storage/ipc.h new file mode 100644 index 00000000000..0da041bc9c8 --- /dev/null +++ b/src/backend/storage/ipc.h @@ -0,0 +1,285 @@ +/*------------------------------------------------------------------------- + * + * ipc.h-- + * POSTGRES inter-process communication definitions. + * + * + * Copyright (c) 1994, Regents of the University of California + * + * $Id: ipc.h,v 1.1.1.1 1996/07/09 06:21:52 scrappy Exp $ + * + * NOTES + * This file is very architecture-specific. This stuff should actually + * be factored into the port/ directories. + * + *------------------------------------------------------------------------- + */ +#ifndef IPC_H +#define IPC_H + +#include <sys/types.h> +#ifndef _IPC_ +#define _IPC_ +#include <sys/ipc.h> +#endif + +#include "c.h" + +/* + * Many architectures have support for user-level spinlocks (i.e., an + * atomic test-and-set instruction). However, we have only written + * spinlock code for the architectures listed. + */ +#if defined(PORTNAME_aix) || \ + defined(PORTNAME_alpha) || \ + defined(PORTNAME_hpux) || \ + defined(PORTNAME_irix5) || \ + defined(PORTNAME_next) || \ + defined(PORTNAME_sparc) || \ + defined(PORTNAME_sparc_solaris) || \ + (defined(__i386__) && defined(__GNUC__)) +#define HAS_TEST_AND_SET +#endif + +#if defined(HAS_TEST_AND_SET) + +#if defined(PORTNAME_next) +/* + * Use Mach mutex routines since these are, in effect, test-and-set + * spinlocks. + */ +#undef NEVER /* definition in cthreads.h conflicts with parse.h */ +#include <mach/cthreads.h> + +typedef struct mutex slock_t; +#else /* next */ +#if defined(PORTNAME_aix) +/* + * The AIX C library has the cs(3) builtin for compare-and-set that + * operates on ints. + */ +typedef unsigned int slock_t; +#else /* aix */ +#if defined(PORTNAME_alpha) +#include <sys/mman.h> +typedef msemaphore slock_t; +#else /* alpha */ +#if defined(PORTNAME_hpux) +/* + * The PA-RISC "semaphore" for the LDWCX instruction is 4 bytes aligned + * to a 16-byte boundary. + */ +typedef struct { int sem[4]; } slock_t; +#else /* hpux */ +#if defined(PORTNAME_irix5) +#include <abi_mutex.h> +typedef abilock_t slock_t; +#else /* irix5 */ +/* + * On all other architectures spinlocks are a single byte. + */ +typedef unsigned char slock_t; +#endif /* irix5 */ +#endif /* hpux */ +#endif /* alpha */ +#endif /* aix */ +#endif /* next */ + +extern void S_LOCK(slock_t *lock); +extern void S_UNLOCK(slock_t *lock); +extern void S_INIT_LOCK(slock_t *lock); + +#if defined(PORTNAME_hpux) || defined(PORTNAME_alpha) || defined(PORTNAME_irix5) || defined(PORTNAME_next) +extern int S_LOCK_FREE(slock_t *lock); +#else /* PORTNAME_hpux */ +#define S_LOCK_FREE(lock) ((*lock) == 0) +#endif /* PORTNAME_hpux */ + +#endif /* HAS_TEST_AND_SET */ + +/* + * On architectures for which we have not implemented spinlocks (or + * cannot do so), we use System V semaphores. We also use them for + * long locks. For some reason union semun is never defined in the + * System V header files so we must do it ourselves. + */ +#if defined(sequent) || \ + defined(PORTNAME_aix) || \ + defined(PORTNAME_alpha) || \ + defined(PORTNAME_hpux) || \ + defined(PORTNAME_sparc_solaris) || \ + defined(WIN32) || \ + defined(PORTNAME_ultrix4) +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; +}; +#endif + +typedef uint16 SystemPortAddress; + +/* semaphore definitions */ + +#define IPCProtection (0600) /* access/modify by user only */ + +#define IPC_NMAXSEM 25 /* maximum number of semaphores */ +#define IpcSemaphoreDefaultStartValue 255 +#define IpcSharedLock (-1) +#define IpcExclusiveLock (-255) + +#define IpcUnknownStatus (-1) +#define IpcInvalidArgument (-2) +#define IpcSemIdExist (-3) +#define IpcSemIdNotExist (-4) + +typedef uint32 IpcSemaphoreKey; /* semaphore key */ +typedef int IpcSemaphoreId; + +/* shared memory definitions */ + +#define IpcMemCreationFailed (-1) +#define IpcMemIdGetFailed (-2) +#define IpcMemAttachFailed 0 + +typedef uint32 IPCKey; +#define PrivateIPCKey IPC_PRIVATE +#define DefaultIPCKey 17317 + +typedef uint32 IpcMemoryKey; /* shared memory key */ +typedef int IpcMemoryId; + + +/* ipc.c */ +extern void exitpg(int code); +extern void quasi_exitpg(void); +extern on_exitpg(void (*function)(), caddr_t arg); + +extern IpcSemaphoreId IpcSemaphoreCreate(IpcSemaphoreKey semKey, + int semNum, int permission, int semStartValue, + int removeOnExit, int *status); +extern void IpcSemaphoreSet(int semId, int semno, int value); +extern void IpcSemaphoreKill(IpcSemaphoreKey key); +extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock); +extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock); +extern int IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem); +extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem); +extern IpcMemoryId IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, + int permission); +extern IpcMemoryId IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size); +extern void IpcMemoryDetach(int status, char *shmaddr); +extern char *IpcMemoryAttach(IpcMemoryId memId); +extern void IpcMemoryKill(IpcMemoryKey memKey); +extern void CreateAndInitSLockMemory(IPCKey key); +extern void AttachSLockMemory(IPCKey key); + + +#ifdef HAS_TEST_AND_SET + +#define NSLOCKS 2048 +#define NOLOCK 0 +#define SHAREDLOCK 1 +#define EXCLUSIVELOCK 2 + +typedef enum _LockId_ { + BUFMGRLOCKID, + LOCKLOCKID, + OIDGENLOCKID, + SHMEMLOCKID, + BINDINGLOCKID, + LOCKMGRLOCKID, + SINVALLOCKID, + +#ifdef MAIN_MEMORY + MMCACHELOCKID, +#endif /* MAIN_MEMORY */ + + PROCSTRUCTLOCKID, + FIRSTFREELOCKID +} _LockId_; + +#define MAX_SPINS FIRSTFREELOCKID + +typedef struct slock { + slock_t locklock; + unsigned char flag; + short nshlocks; + slock_t shlock; + slock_t exlock; + slock_t comlock; + struct slock *next; +} SLock; + +extern void ExclusiveLock(int lockid); +extern void ExclusiveUnlock(int lockid); +extern bool LockIsFree(int lockid); +#else /* HAS_TEST_AND_SET */ + +typedef enum _LockId_ { + SHMEMLOCKID, + BINDINGLOCKID, + BUFMGRLOCKID, + LOCKMGRLOCKID, + SINVALLOCKID, + +#ifdef MAIN_MEMORY + MMCACHELOCKID, +#endif /* MAIN_MEMORY */ + + PROCSTRUCTLOCKID, + OIDGENLOCKID, + FIRSTFREELOCKID +} _LockId_; + +#define MAX_SPINS FIRSTFREELOCKID + +#endif /* HAS_TEST_AND_SET */ + +/* + * the following are originally in ipci.h but the prototypes have circular + * dependencies and most files include both ipci.h and ipc.h anyway, hence + * combined. + * + */ + +/* + * Note: + * These must not hash to DefaultIPCKey or PrivateIPCKey. + */ +#define SystemPortAddressGetIPCKey(address) \ + (28597 * (address) + 17491) + +/* + * these keys are originally numbered from 1 to 12 consecutively but not + * all are used. The unused ones are removed. - ay 4/95. + */ +#define IPCKeyGetBufferMemoryKey(key) \ + ((key == PrivateIPCKey) ? key : 1 + (key)) + +#define IPCKeyGetSIBufferMemoryBlock(key) \ + ((key == PrivateIPCKey) ? key : 7 + (key)) + +#define IPCKeyGetSLockSharedMemoryKey(key) \ + ((key == PrivateIPCKey) ? key : 10 + (key)) + +#define IPCKeyGetSpinLockSemaphoreKey(key) \ + ((key == PrivateIPCKey) ? key : 11 + (key)) +#define IPCKeyGetWaitIOSemaphoreKey(key) \ + ((key == PrivateIPCKey) ? key : 12 + (key)) + +/* -------------------------- + * NOTE: This macro must always give the highest numbered key as every backend + * process forked off by the postmaster will be trying to acquire a semaphore + * with a unique key value starting at key+14 and incrementing up. Each + * backend uses the current key value then increments it by one. + * -------------------------- + */ +#define IPCGetProcessSemaphoreInitKey(key) \ + ((key == PrivateIPCKey) ? key : 14 + (key)) + +/* ipci.c */ +extern IPCKey SystemPortAddressCreateIPCKey(SystemPortAddress address); +extern void CreateSharedMemoryAndSemaphores(IPCKey key); +extern void AttachSharedMemoryAndSemaphores(IPCKey key); + +#endif /* IPC_H */ |