1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00
Files
postgres/src/include/storage/ipc.h
1996-11-04 04:00:56 +00:00

287 lines
7.0 KiB
C

/*-------------------------------------------------------------------------
*
* ipc.h--
* POSTGRES inter-process communication definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: ipc.h,v 1.9 1996/11/04 04:00:28 momjian Exp $
*
* NOTES
* This file is very architecture-specific. This stuff should actually
* be factored into the port/ directories.
*
*-------------------------------------------------------------------------
*/
#ifndef IPC_H
#define IPC_H
#ifndef _IPC_
#define _IPC_
#endif
#include <sys/types.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.
* NB: for operating systems like NetBSD (covered by BSD44_derived),
* we may in fact have different architectures, thus make the tests
* based on portnames somewhat misleading.
*/
#if defined(aix) || \
defined(alpha) || \
defined(BSD44_derived) || \
defined(bsdi) || \
defined(hpux) || \
defined(i386_solaris) || \
defined(irix5) || \
defined(linux) || \
defined(next) || \
defined(sparc) || \
defined(sparc_solaris)
#define HAS_TEST_AND_SET
#endif
#if defined(BSD44_derived) && defined(__mips__)
#undef HAS_TEST_AND_SET
#endif
#if defined(HAS_TEST_AND_SET)
#if defined(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(alpha)
typedef msemaphore slock_t;
#else /* alpha */
#if defined(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(irix5)
typedef abilock_t slock_t;
#else /* irix5 */
#if defined(next)
/*
* Use Mach mutex routines since these are, in effect, test-and-set
* spinlocks.
*/
#undef NEVER /* definition in cthreads.h conflicts with parse.h */
typedef struct mutex slock_t;
#else /* next */
/*
* On all other architectures spinlocks are a single byte.
*/
typedef unsigned char slock_t;
#endif /* next */
#endif /* irix5 */
#endif /* hpux */
#endif /* alpha */
#endif /* aix */
extern void S_LOCK(slock_t *lock);
extern void S_UNLOCK(slock_t *lock);
extern void S_INIT_LOCK(slock_t *lock);
#if defined(alpha) || \
defined(hpux) || \
defined(irix5) || \
defined(next)
extern int S_LOCK_FREE(slock_t *lock);
#else
#define S_LOCK_FREE(lock) ((*lock) == 0)
#endif
#endif /* HAS_TEST_AND_SET */
#ifdef NEED_UNION_SEMUN
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 */