aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1997-09-07 05:04:48 +0000
committerBruce Momjian <bruce@momjian.us>1997-09-07 05:04:48 +0000
commit1ccd423235a48739d6f7a4d7889705b5f9ecc69b (patch)
tree8001c4e839dfad8f29ceda7f8c5f5dbb8759b564 /src/backend/storage/ipc
parent8fecd4febf8357f3cc20383ed29ced484877d5ac (diff)
downloadpostgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.tar.gz
postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.zip
Massive commit to run PGINDENT on all *.c and *.h files.
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r--src/backend/storage/ipc/ipc.c991
-rw-r--r--src/backend/storage/ipc/ipci.c178
-rw-r--r--src/backend/storage/ipc/s_lock.c384
-rw-r--r--src/backend/storage/ipc/shmem.c951
-rw-r--r--src/backend/storage/ipc/shmqueue.c274
-rw-r--r--src/backend/storage/ipc/sinval.c222
-rw-r--r--src/backend/storage/ipc/sinvaladt.c1129
-rw-r--r--src/backend/storage/ipc/spin.c246
8 files changed, 2276 insertions, 2099 deletions
diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c
index a5573e89151..3dd6d2ec094 100644
--- a/src/backend/storage/ipc/ipc.c
+++ b/src/backend/storage/ipc/ipc.c
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* ipc.c--
- * POSTGRES inter-process communication definitions.
+ * POSTGRES inter-process communication definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.11 1997/08/19 21:32:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.12 1997/09/07 04:48:30 momjian Exp $
*
* NOTES
*
- * Currently, semaphores are used (my understanding anyway) in two
- * different ways:
- * 1. as mutexes on machines that don't have test-and-set (eg.
- * mips R3000).
- * 2. for putting processes to sleep when waiting on a lock
- * and waking them up when the lock is free.
- * The number of semaphores in (1) is fixed and those are shared
- * among all backends. In (2), there is 1 semaphore per process and those
- * are not shared with anyone else.
- * -ay 4/95
+ * Currently, semaphores are used (my understanding anyway) in two
+ * different ways:
+ * 1. as mutexes on machines that don't have test-and-set (eg.
+ * mips R3000).
+ * 2. for putting processes to sleep when waiting on a lock
+ * and waking them up when the lock is free.
+ * The number of semaphores in (1) is fixed and those are shared
+ * among all backends. In (2), there is 1 semaphore per process and those
+ * are not shared with anyone else.
+ * -ay 4/95
*
*-------------------------------------------------------------------------
*/
@@ -44,94 +44,98 @@
#endif
#if defined(bsd44)
-int UsePrivateMemory = 1;
+int UsePrivateMemory = 1;
+
#else
-int UsePrivateMemory = 0;
+int UsePrivateMemory = 0;
+
#endif
-static void IpcMemoryDetach(int status, char *shmaddr);
+static void IpcMemoryDetach(int status, char *shmaddr);
/* ----------------------------------------------------------------
- * exit() handling stuff
+ * exit() handling stuff
* ----------------------------------------------------------------
*/
#define MAX_ON_EXITS 20
-static struct ONEXIT {
- void (*function)();
- caddr_t arg;
-} onexit_list[ MAX_ON_EXITS ];
+static struct ONEXIT
+{
+ void (*function) ();
+ caddr_t arg;
+} onexit_list[MAX_ON_EXITS];
-static int onexit_index;
-static void IpcConfigTip(void);
+static int onexit_index;
+static void IpcConfigTip(void);
-typedef struct _PrivateMemStruct {
- int id;
- char *memptr;
-} PrivateMem;
+typedef struct _PrivateMemStruct
+{
+ int id;
+ char *memptr;
+} PrivateMem;
-PrivateMem IpcPrivateMem[16];
+PrivateMem IpcPrivateMem[16];
static int
PrivateMemoryCreate(IpcMemoryKey memKey,
- uint32 size)
+ uint32 size)
{
- static int memid = 0;
-
- UsePrivateMemory = 1;
-
- IpcPrivateMem[memid].id = memid;
- IpcPrivateMem[memid].memptr = malloc(size);
- if (IpcPrivateMem[memid].memptr == NULL)
- elog(WARN, "PrivateMemoryCreate: not enough memory to malloc");
- memset(IpcPrivateMem[memid].memptr, 0, size); /* XXX PURIFY */
-
- return (memid++);
+ static int memid = 0;
+
+ UsePrivateMemory = 1;
+
+ IpcPrivateMem[memid].id = memid;
+ IpcPrivateMem[memid].memptr = malloc(size);
+ if (IpcPrivateMem[memid].memptr == NULL)
+ elog(WARN, "PrivateMemoryCreate: not enough memory to malloc");
+ memset(IpcPrivateMem[memid].memptr, 0, size); /* XXX PURIFY */
+
+ return (memid++);
}
-static char *
+static char *
PrivateMemoryAttach(IpcMemoryId memid)
{
- return ( IpcPrivateMem[memid].memptr );
+ return (IpcPrivateMem[memid].memptr);
}
/* ----------------------------------------------------------------
- * exitpg
+ * exitpg
*
- * this function calls all the callbacks registered
- * for it (to free resources) and then calls exit.
- * This should be the only function to call exit().
- * -cim 2/6/90
+ * this function calls all the callbacks registered
+ * for it (to free resources) and then calls exit.
+ * This should be the only function to call exit().
+ * -cim 2/6/90
* ----------------------------------------------------------------
*/
-static int exitpg_inprogress = 0;
+static int exitpg_inprogress = 0;
void
exitpg(int code)
{
- int i;
-
- /* ----------------
- * if exitpg_inprocess is true, then it means that we
- * are being invoked from within an on_exit() handler
- * and so we return immediately to avoid recursion.
- * ----------------
- */
- if (exitpg_inprogress)
- return;
-
- exitpg_inprogress = 1;
-
- /* ----------------
- * call all the callbacks registered before calling exit().
- * ----------------
- */
- for (i = onexit_index - 1; i >= 0; --i)
- (*onexit_list[i].function)(code, onexit_list[i].arg);
-
- exit(code);
+ int i;
+
+ /* ----------------
+ * if exitpg_inprocess is true, then it means that we
+ * are being invoked from within an on_exit() handler
+ * and so we return immediately to avoid recursion.
+ * ----------------
+ */
+ if (exitpg_inprogress)
+ return;
+
+ exitpg_inprogress = 1;
+
+ /* ----------------
+ * call all the callbacks registered before calling exit().
+ * ----------------
+ */
+ for (i = onexit_index - 1; i >= 0; --i)
+ (*onexit_list[i].function) (code, onexit_list[i].arg);
+
+ exit(code);
}
/* ------------------
@@ -143,591 +147,628 @@ exitpg(int code)
void
quasi_exitpg()
{
- int i;
-
- /* ----------------
- * if exitpg_inprocess is true, then it means that we
- * are being invoked from within an on_exit() handler
- * and so we return immediately to avoid recursion.
- * ----------------
- */
- if (exitpg_inprogress)
- return;
-
- exitpg_inprogress = 1;
-
- /* ----------------
- * call all the callbacks registered before calling exit().
- * ----------------
- */
- for (i = onexit_index - 1; i >= 0; --i)
- (*onexit_list[i].function)(0, onexit_list[i].arg);
-
- onexit_index = 0;
- exitpg_inprogress = 0;
+ int i;
+
+ /* ----------------
+ * if exitpg_inprocess is true, then it means that we
+ * are being invoked from within an on_exit() handler
+ * and so we return immediately to avoid recursion.
+ * ----------------
+ */
+ if (exitpg_inprogress)
+ return;
+
+ exitpg_inprogress = 1;
+
+ /* ----------------
+ * call all the callbacks registered before calling exit().
+ * ----------------
+ */
+ for (i = onexit_index - 1; i >= 0; --i)
+ (*onexit_list[i].function) (0, onexit_list[i].arg);
+
+ onexit_index = 0;
+ exitpg_inprogress = 0;
}
/* ----------------------------------------------------------------
- * on_exitpg
+ * on_exitpg
*
- * this function adds a callback function to the list of
- * functions invoked by exitpg(). -cim 2/6/90
+ * this function adds a callback function to the list of
+ * functions invoked by exitpg(). -cim 2/6/90
* ----------------------------------------------------------------
*/
int
-on_exitpg(void (*function)(), caddr_t arg)
+ on_exitpg(void (*function) (), caddr_t arg)
{
- if (onexit_index >= MAX_ON_EXITS)
- return(-1);
-
- onexit_list[ onexit_index ].function = function;
- onexit_list[ onexit_index ].arg = arg;
-
- ++onexit_index;
-
- return(0);
+ if (onexit_index >= MAX_ON_EXITS)
+ return (-1);
+
+ onexit_list[onexit_index].function = function;
+ onexit_list[onexit_index].arg = arg;
+
+ ++onexit_index;
+
+ return (0);
}
/****************************************************************************/
-/* IPCPrivateSemaphoreKill(status, semId) */
-/* */
+/* IPCPrivateSemaphoreKill(status, semId) */
+/* */
/****************************************************************************/
static void
IPCPrivateSemaphoreKill(int status,
- int semId) /* caddr_t */
+ int semId) /* caddr_t */
{
- union semun semun;
- semctl(semId, 0, IPC_RMID, semun);
+ union semun semun;
+
+ semctl(semId, 0, IPC_RMID, semun);
}
/****************************************************************************/
-/* IPCPrivateMemoryKill(status, shmId) */
-/* */
+/* IPCPrivateMemoryKill(status, shmId) */
+/* */
/****************************************************************************/
static void
IPCPrivateMemoryKill(int status,
- int shmId) /* caddr_t */
+ int shmId) /* caddr_t */
{
- if ( UsePrivateMemory ) {
- /* free ( IpcPrivateMem[shmId].memptr ); */
- } else {
- if (shmctl(shmId, IPC_RMID, (struct shmid_ds *) NULL) < 0) {
- elog(NOTICE, "IPCPrivateMemoryKill: shmctl(%d, %d, 0) failed: %m",
- shmId, IPC_RMID);
+ if (UsePrivateMemory)
+ {
+ /* free ( IpcPrivateMem[shmId].memptr ); */
+ }
+ else
+ {
+ if (shmctl(shmId, IPC_RMID, (struct shmid_ds *) NULL) < 0)
+ {
+ elog(NOTICE, "IPCPrivateMemoryKill: shmctl(%d, %d, 0) failed: %m",
+ shmId, IPC_RMID);
+ }
}
- }
}
/****************************************************************************/
-/* IpcSemaphoreCreate(semKey, semNum, permission, semStartValue) */
-/* */
-/* - returns a semaphore identifier: */
-/* */
+/* IpcSemaphoreCreate(semKey, semNum, permission, semStartValue) */
+/* */
+/* - returns a semaphore identifier: */
+/* */
/* if key doesn't exist: return a new id, status:= IpcSemIdNotExist */
-/* if key exists: return the old id, status:= IpcSemIdExist */
-/* if semNum > MAX : return # of argument, status:=IpcInvalidArgument */
-/* */
+/* if key exists: return the old id, status:= IpcSemIdExist */
+/* if semNum > MAX : return # of argument, status:=IpcInvalidArgument */
+/* */
/****************************************************************************/
/*
* Note:
- * XXX This should be split into two different calls. One should
- * XXX be used to create a semaphore set. The other to "attach" a
+ * XXX This should be split into two different calls. One should
+ * XXX be used to create a semaphore set. The other to "attach" a
* XXX existing set. It should be an error for the semaphore set
* XXX to to already exist or for it not to, respectively.
*
- * Currently, the semaphore sets are "attached" and an error
- * is detected only when a later shared memory attach fails.
+ * Currently, the semaphore sets are "attached" and an error
+ * is detected only when a later shared memory attach fails.
*/
IpcSemaphoreId
IpcSemaphoreCreate(IpcSemaphoreKey semKey,
- int semNum,
- int permission,
- int semStartValue,
- int removeOnExit,
- int *status)
+ int semNum,
+ int permission,
+ int semStartValue,
+ int removeOnExit,
+ int *status)
{
- int i;
- int errStatus;
- int semId;
- u_short array[IPC_NMAXSEM];
- union semun semun;
-
- /* get a semaphore if non-existent */
- /* check arguments */
- if (semNum > IPC_NMAXSEM || semNum <= 0) {
- *status = IpcInvalidArgument;
- return(2); /* returns the number of the invalid argument */
- }
-
- semId = semget(semKey, 0, 0);
-
- if (semId == -1) {
- *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */
+ int i;
+ int errStatus;
+ int semId;
+ u_short array[IPC_NMAXSEM];
+ union semun semun;
+
+ /* get a semaphore if non-existent */
+ /* check arguments */
+ if (semNum > IPC_NMAXSEM || semNum <= 0)
+ {
+ *status = IpcInvalidArgument;
+ return (2); /* returns the number of the invalid
+ * argument */
+ }
+
+ semId = semget(semKey, 0, 0);
+
+ if (semId == -1)
+ {
+ *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */
#ifdef DEBUG_IPC
- fprintf(stderr,"calling semget with %d, %d , %d\n",
- semKey,
- semNum,
- IPC_CREAT|permission );
+ fprintf(stderr, "calling semget with %d, %d , %d\n",
+ semKey,
+ semNum,
+ IPC_CREAT | permission);
#endif
- semId = semget(semKey, semNum, IPC_CREAT|permission);
+ semId = semget(semKey, semNum, IPC_CREAT | permission);
+
+ if (semId < 0)
+ {
+ perror("semget");
+ IpcConfigTip();
+ exitpg(3);
+ }
+ for (i = 0; i < semNum; i++)
+ {
+ array[i] = semStartValue;
+ }
+ semun.array = array;
+ errStatus = semctl(semId, 0, SETALL, semun);
+ if (errStatus == -1)
+ {
+ perror("semctl");
+ IpcConfigTip();
+ }
+
+ if (removeOnExit)
+ on_exitpg(IPCPrivateSemaphoreKill, (caddr_t) semId);
- if (semId < 0) {
- perror("semget");
- IpcConfigTip();
- exitpg(3);
- }
- for (i = 0; i < semNum; i++) {
- array[i] = semStartValue;
}
- semun.array = array;
- errStatus = semctl(semId, 0, SETALL, semun);
- if (errStatus == -1) {
- perror("semctl");
- IpcConfigTip();
+ else
+ {
+ /* there is a semaphore id for this key */
+ *status = IpcSemIdExist;
}
-
- if (removeOnExit)
- on_exitpg(IPCPrivateSemaphoreKill, (caddr_t)semId);
-
- } else {
- /* there is a semaphore id for this key */
- *status = IpcSemIdExist;
- }
-
+
#ifdef DEBUG_IPC
- fprintf(stderr,"\nIpcSemaphoreCreate, status %d, returns %d\n",
- *status,
- semId );
- fflush(stdout);
- fflush(stderr);
+ fprintf(stderr, "\nIpcSemaphoreCreate, status %d, returns %d\n",
+ *status,
+ semId);
+ fflush(stdout);
+ fflush(stderr);
#endif
- return(semId);
+ return (semId);
}
/****************************************************************************/
-/* IpcSemaphoreSet() - sets the initial value of the semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreSet() - sets the initial value of the semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
#ifdef NOT_USED
-static int IpcSemaphoreSet_return;
+static int IpcSemaphoreSet_return;
void
IpcSemaphoreSet(int semId, int semno, int value)
{
- int errStatus;
- union semun semun;
-
- semun.val = value;
- errStatus = semctl(semId, semno, SETVAL, semun);
- IpcSemaphoreSet_return = errStatus;
-
- if (errStatus == -1)
- {
- perror("semctl");
- IpcConfigTip();
- }
+ int errStatus;
+ union semun semun;
+
+ semun.val = value;
+ errStatus = semctl(semId, semno, SETVAL, semun);
+ IpcSemaphoreSet_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semctl");
+ IpcConfigTip();
+ }
}
+
#endif
/****************************************************************************/
-/* IpcSemaphoreKill(key) - removes a semaphore */
-/* */
+/* IpcSemaphoreKill(key) - removes a semaphore */
+/* */
/****************************************************************************/
void
IpcSemaphoreKill(IpcSemaphoreKey key)
{
- int semId;
- union semun semun;
-
- /* kill semaphore if existent */
-
- semId = semget(key, 0, 0);
- if (semId != -1)
- semctl(semId, 0, IPC_RMID, semun);
+ int semId;
+ union semun semun;
+
+ /* kill semaphore if existent */
+
+ semId = semget(key, 0, 0);
+ if (semId != -1)
+ semctl(semId, 0, IPC_RMID, semun);
}
/****************************************************************************/
-/* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
-static int IpcSemaphoreLock_return;
+static int IpcSemaphoreLock_return;
void
IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock)
{
- extern int errno;
- int errStatus;
- struct sembuf sops;
-
- sops.sem_op = lock;
- sops.sem_flg = 0;
- sops.sem_num = sem;
-
- /* ----------------
- * Note: if errStatus is -1 and errno == EINTR then it means we
- * returned from the operation prematurely because we were
- * sent a signal. So we try and lock the semaphore again.
- * I am not certain this is correct, but the semantics aren't
- * clear it fixes problems with parallel abort synchronization,
- * namely that after processing an abort signal, the semaphore
- * call returns with -1 (and errno == EINTR) before it should.
- * -cim 3/28/90
- * ----------------
- */
- do {
- errStatus = semop(semId, &sops, 1);
- } while (errStatus == -1 && errno == EINTR);
-
- IpcSemaphoreLock_return = errStatus;
-
- if (errStatus == -1) {
- perror("semop");
- IpcConfigTip();
- exitpg(255);
- }
+ extern int errno;
+ int errStatus;
+ struct sembuf sops;
+
+ sops.sem_op = lock;
+ sops.sem_flg = 0;
+ sops.sem_num = sem;
+
+ /* ----------------
+ * Note: if errStatus is -1 and errno == EINTR then it means we
+ * returned from the operation prematurely because we were
+ * sent a signal. So we try and lock the semaphore again.
+ * I am not certain this is correct, but the semantics aren't
+ * clear it fixes problems with parallel abort synchronization,
+ * namely that after processing an abort signal, the semaphore
+ * call returns with -1 (and errno == EINTR) before it should.
+ * -cim 3/28/90
+ * ----------------
+ */
+ do
+ {
+ errStatus = semop(semId, &sops, 1);
+ } while (errStatus == -1 && errno == EINTR);
+
+ IpcSemaphoreLock_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semop");
+ IpcConfigTip();
+ exitpg(255);
+ }
}
/****************************************************************************/
-/* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
-static int IpcSemaphoreUnlock_return;
+static int IpcSemaphoreUnlock_return;
void
IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock)
{
- extern int errno;
- int errStatus;
- struct sembuf sops;
-
- sops.sem_op = -lock;
- sops.sem_flg = 0;
- sops.sem_num = sem;
-
-
- /* ----------------
- * Note: if errStatus is -1 and errno == EINTR then it means we
- * returned from the operation prematurely because we were
- * sent a signal. So we try and lock the semaphore again.
- * I am not certain this is correct, but the semantics aren't
- * clear it fixes problems with parallel abort synchronization,
- * namely that after processing an abort signal, the semaphore
- * call returns with -1 (and errno == EINTR) before it should.
- * -cim 3/28/90
- * ----------------
- */
- do {
- errStatus = semop(semId, &sops, 1);
- } while (errStatus == -1 && errno == EINTR);
-
- IpcSemaphoreUnlock_return = errStatus;
-
- if (errStatus == -1) {
- perror("semop");
- IpcConfigTip();
- exitpg(255);
- }
+ extern int errno;
+ int errStatus;
+ struct sembuf sops;
+
+ sops.sem_op = -lock;
+ sops.sem_flg = 0;
+ sops.sem_num = sem;
+
+
+ /* ----------------
+ * Note: if errStatus is -1 and errno == EINTR then it means we
+ * returned from the operation prematurely because we were
+ * sent a signal. So we try and lock the semaphore again.
+ * I am not certain this is correct, but the semantics aren't
+ * clear it fixes problems with parallel abort synchronization,
+ * namely that after processing an abort signal, the semaphore
+ * call returns with -1 (and errno == EINTR) before it should.
+ * -cim 3/28/90
+ * ----------------
+ */
+ do
+ {
+ errStatus = semop(semId, &sops, 1);
+ } while (errStatus == -1 && errno == EINTR);
+
+ IpcSemaphoreUnlock_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semop");
+ IpcConfigTip();
+ exitpg(255);
+ }
}
int
-IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem)
+IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem)
{
- int semncnt;
- union semun dummy; /* for Solaris */
-
- semncnt = semctl(semId, sem, GETNCNT, dummy);
- return semncnt;
+ int semncnt;
+ union semun dummy; /* for Solaris */
+
+ semncnt = semctl(semId, sem, GETNCNT, dummy);
+ return semncnt;
}
int
-IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem)
+IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem)
{
- int semval;
- union semun dummy; /* for Solaris */
-
- semval = semctl(semId, sem, GETVAL, dummy);
- return semval;
+ int semval;
+ union semun dummy; /* for Solaris */
+
+ semval = semctl(semId, sem, GETVAL, dummy);
+ return semval;
}
/****************************************************************************/
-/* IpcMemoryCreate(memKey) */
-/* */
-/* - returns the memory identifier, if creation succeeds */
-/* returns IpcMemCreationFailed, if failure */
+/* IpcMemoryCreate(memKey) */
+/* */
+/* - returns the memory identifier, if creation succeeds */
+/* returns IpcMemCreationFailed, if failure */
/****************************************************************************/
IpcMemoryId
IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission)
{
- IpcMemoryId shmid;
-
- if (memKey == PrivateIPCKey) {
- /* private */
- shmid = PrivateMemoryCreate(memKey, size);
- }else {
- shmid = shmget(memKey, size, IPC_CREAT|permission);
- }
-
- if (shmid < 0) {
- fprintf(stderr,"IpcMemoryCreate: memKey=%d , size=%d , permission=%d",
- memKey, size , permission );
- perror("IpcMemoryCreate: shmget(..., create, ...) failed");
- IpcConfigTip();
- return(IpcMemCreationFailed);
- }
-
- /* if (memKey == PrivateIPCKey) */
- on_exitpg(IPCPrivateMemoryKill, (caddr_t)shmid);
-
- return(shmid);
+ IpcMemoryId shmid;
+
+ if (memKey == PrivateIPCKey)
+ {
+ /* private */
+ shmid = PrivateMemoryCreate(memKey, size);
+ }
+ else
+ {
+ shmid = shmget(memKey, size, IPC_CREAT | permission);
+ }
+
+ if (shmid < 0)
+ {
+ fprintf(stderr, "IpcMemoryCreate: memKey=%d , size=%d , permission=%d",
+ memKey, size, permission);
+ perror("IpcMemoryCreate: shmget(..., create, ...) failed");
+ IpcConfigTip();
+ return (IpcMemCreationFailed);
+ }
+
+ /* if (memKey == PrivateIPCKey) */
+ on_exitpg(IPCPrivateMemoryKill, (caddr_t) shmid);
+
+ return (shmid);
}
/****************************************************************************/
-/* IpcMemoryIdGet(memKey, size) returns the shared memory Id */
-/* or IpcMemIdGetFailed */
+/* IpcMemoryIdGet(memKey, size) returns the shared memory Id */
+/* or IpcMemIdGetFailed */
/****************************************************************************/
IpcMemoryId
IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size)
{
- IpcMemoryId shmid;
-
- shmid = shmget(memKey, size, 0);
-
- if (shmid < 0) {
- fprintf(stderr,"IpcMemoryIdGet: memKey=%d , size=%d , permission=%d",
- memKey, size , 0 );
- perror("IpcMemoryIdGet: shmget() failed");
- IpcConfigTip();
- return(IpcMemIdGetFailed);
- }
-
- return(shmid);
+ IpcMemoryId shmid;
+
+ shmid = shmget(memKey, size, 0);
+
+ if (shmid < 0)
+ {
+ fprintf(stderr, "IpcMemoryIdGet: memKey=%d , size=%d , permission=%d",
+ memKey, size, 0);
+ perror("IpcMemoryIdGet: shmget() failed");
+ IpcConfigTip();
+ return (IpcMemIdGetFailed);
+ }
+
+ return (shmid);
}
/****************************************************************************/
-/* IpcMemoryDetach(status, shmaddr) removes a shared memory segment */
-/* from a backend address space */
-/* (only called by backends running under the postmaster) */
+/* IpcMemoryDetach(status, shmaddr) removes a shared memory segment */
+/* from a backend address space */
+/* (only called by backends running under the postmaster) */
/****************************************************************************/
static void
IpcMemoryDetach(int status, char *shmaddr)
{
- if (shmdt(shmaddr) < 0) {
- elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr);
- }
+ if (shmdt(shmaddr) < 0)
+ {
+ elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr);
+ }
}
/****************************************************************************/
-/* IpcMemoryAttach(memId) returns the adress of shared memory */
-/* or IpcMemAttachFailed */
-/* */
-/* CALL IT: addr = (struct <MemoryStructure> *) IpcMemoryAttach(memId); */
-/* */
+/* IpcMemoryAttach(memId) returns the adress of shared memory */
+/* or IpcMemAttachFailed */
+/* */
+/* CALL IT: addr = (struct <MemoryStructure> *) IpcMemoryAttach(memId); */
+/* */
/****************************************************************************/
-char *
+char *
IpcMemoryAttach(IpcMemoryId memId)
{
- char *memAddress;
-
- if (UsePrivateMemory) {
- memAddress = (char *) PrivateMemoryAttach(memId);
- } else {
- memAddress = (char *) shmat(memId, 0, 0);
- }
-
- /* if ( *memAddress == -1) { XXX ??? */
- if ( memAddress == (char *)-1) {
- perror("IpcMemoryAttach: shmat() failed");
- IpcConfigTip();
- return(IpcMemAttachFailed);
- }
-
- if (!UsePrivateMemory)
- on_exitpg(IpcMemoryDetach, (caddr_t) memAddress);
-
- return((char *) memAddress);
+ char *memAddress;
+
+ if (UsePrivateMemory)
+ {
+ memAddress = (char *) PrivateMemoryAttach(memId);
+ }
+ else
+ {
+ memAddress = (char *) shmat(memId, 0, 0);
+ }
+
+ /* if ( *memAddress == -1) { XXX ??? */
+ if (memAddress == (char *) -1)
+ {
+ perror("IpcMemoryAttach: shmat() failed");
+ IpcConfigTip();
+ return (IpcMemAttachFailed);
+ }
+
+ if (!UsePrivateMemory)
+ on_exitpg(IpcMemoryDetach, (caddr_t) memAddress);
+
+ return ((char *) memAddress);
}
/****************************************************************************/
-/* IpcMemoryKill(memKey) removes a shared memory segment */
-/* (only called by the postmaster and standalone backends) */
+/* IpcMemoryKill(memKey) removes a shared memory segment */
+/* (only called by the postmaster and standalone backends) */
/****************************************************************************/
void
IpcMemoryKill(IpcMemoryKey memKey)
-{
- IpcMemoryId shmid;
-
- if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0) {
- if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0) {
- elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m",
- shmid, IPC_RMID);
+{
+ IpcMemoryId shmid;
+
+ if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0)
+ {
+ if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0)
+ {
+ elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m",
+ shmid, IPC_RMID);
+ }
}
- }
-}
+}
#ifdef HAS_TEST_AND_SET
/* ------------------
- * use hardware locks to replace semaphores for sequent machines
- * to avoid costs of swapping processes and to provide unlimited
- * supply of locks.
+ * use hardware locks to replace semaphores for sequent machines
+ * to avoid costs of swapping processes and to provide unlimited
+ * supply of locks.
* ------------------
*/
-static SLock *SLockArray = NULL;
-static SLock **FreeSLockPP;
-static int *UnusedSLockIP;
+static SLock *SLockArray = NULL;
+static SLock **FreeSLockPP;
+static int *UnusedSLockIP;
static slock_t *SLockMemoryLock;
static IpcMemoryId SLockMemoryId = -1;
-struct ipcdummy { /* to get alignment/size right */
- SLock *free;
- int unused;
- slock_t memlock;
- SLock slocks[NSLOCKS];
+struct ipcdummy
+{ /* to get alignment/size right */
+ SLock *free;
+ int unused;
+ slock_t memlock;
+ SLock slocks[NSLOCKS];
};
-static int SLockMemorySize = sizeof(struct ipcdummy);
+static int SLockMemorySize = sizeof(struct ipcdummy);
void
CreateAndInitSLockMemory(IPCKey key)
{
- int id;
- SLock *slckP;
-
- SLockMemoryId = IpcMemoryCreate(key,
- SLockMemorySize,
- 0700);
- AttachSLockMemory(key);
- *FreeSLockPP = NULL;
- *UnusedSLockIP = (int)FIRSTFREELOCKID;
- for (id=0; id<(int)FIRSTFREELOCKID; id++) {
- slckP = &(SLockArray[id]);
- S_INIT_LOCK(&(slckP->locklock));
- slckP->flag = NOLOCK;
- slckP->nshlocks = 0;
- S_INIT_LOCK(&(slckP->shlock));
- S_INIT_LOCK(&(slckP->exlock));
- S_INIT_LOCK(&(slckP->comlock));
- slckP->next = NULL;
- }
- return;
+ int id;
+ SLock *slckP;
+
+ SLockMemoryId = IpcMemoryCreate(key,
+ SLockMemorySize,
+ 0700);
+ AttachSLockMemory(key);
+ *FreeSLockPP = NULL;
+ *UnusedSLockIP = (int) FIRSTFREELOCKID;
+ for (id = 0; id < (int) FIRSTFREELOCKID; id++)
+ {
+ slckP = &(SLockArray[id]);
+ S_INIT_LOCK(&(slckP->locklock));
+ slckP->flag = NOLOCK;
+ slckP->nshlocks = 0;
+ S_INIT_LOCK(&(slckP->shlock));
+ S_INIT_LOCK(&(slckP->exlock));
+ S_INIT_LOCK(&(slckP->comlock));
+ slckP->next = NULL;
+ }
+ return;
}
void
AttachSLockMemory(IPCKey key)
{
- struct ipcdummy *slockM;
-
- if (SLockMemoryId == -1)
- SLockMemoryId = IpcMemoryIdGet(key,SLockMemorySize);
- if (SLockMemoryId == -1)
- elog(FATAL, "SLockMemory not in shared memory");
- slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId);
- if (slockM == IpcMemAttachFailed)
- elog(FATAL, "AttachSLockMemory: could not attach segment");
- FreeSLockPP = (SLock **) &(slockM->free);
- UnusedSLockIP = (int *) &(slockM->unused);
- SLockMemoryLock = (slock_t *) &(slockM->memlock);
- S_INIT_LOCK(SLockMemoryLock);
- SLockArray = (SLock *) &(slockM->slocks[0]);
- return;
+ struct ipcdummy *slockM;
+
+ if (SLockMemoryId == -1)
+ SLockMemoryId = IpcMemoryIdGet(key, SLockMemorySize);
+ if (SLockMemoryId == -1)
+ elog(FATAL, "SLockMemory not in shared memory");
+ slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId);
+ if (slockM == IpcMemAttachFailed)
+ elog(FATAL, "AttachSLockMemory: could not attach segment");
+ FreeSLockPP = (SLock **) & (slockM->free);
+ UnusedSLockIP = (int *) &(slockM->unused);
+ SLockMemoryLock = (slock_t *) & (slockM->memlock);
+ S_INIT_LOCK(SLockMemoryLock);
+ SLockArray = (SLock *) & (slockM->slocks[0]);
+ return;
}
#ifdef LOCKDEBUG
#define PRINT_LOCK(LOCK) printf("(locklock = %d, flag = %d, nshlocks = %d, \
shlock = %d, exlock =%d)\n", LOCK->locklock, \
- LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
- LOCK->exlock)
+ LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
+ LOCK->exlock)
#endif
void
ExclusiveLock(int lockid)
{
- SLock *slckP;
- slckP = &(SLockArray[lockid]);
+ SLock *slckP;
+
+ slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
- printf("ExclusiveLock(%d)\n", lockid);
- printf("IN: ");
- PRINT_LOCK(slckP);
+ printf("ExclusiveLock(%d)\n", lockid);
+ printf("IN: ");
+ PRINT_LOCK(slckP);
#endif
- ex_try_again:
- S_LOCK(&(slckP->locklock));
- switch (slckP->flag) {
- case NOLOCK:
- slckP->flag = EXCLUSIVELOCK;
- S_LOCK(&(slckP->exlock));
- S_LOCK(&(slckP->shlock));
- S_UNLOCK(&(slckP->locklock));
+ex_try_again:
+ S_LOCK(&(slckP->locklock));
+ switch (slckP->flag)
+ {
+ case NOLOCK:
+ slckP->flag = EXCLUSIVELOCK;
+ S_LOCK(&(slckP->exlock));
+ S_LOCK(&(slckP->shlock));
+ S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
- printf("OUT: ");
- PRINT_LOCK(slckP);
+ printf("OUT: ");
+ PRINT_LOCK(slckP);
#endif
- return;
- case SHAREDLOCK:
- case EXCLUSIVELOCK:
- S_UNLOCK(&(slckP->locklock));
- S_LOCK(&(slckP->exlock));
- S_UNLOCK(&(slckP->exlock));
- goto ex_try_again;
- }
+ return;
+ case SHAREDLOCK:
+ case EXCLUSIVELOCK:
+ S_UNLOCK(&(slckP->locklock));
+ S_LOCK(&(slckP->exlock));
+ S_UNLOCK(&(slckP->exlock));
+ goto ex_try_again;
+ }
}
void
ExclusiveUnlock(int lockid)
{
- SLock *slckP;
-
- slckP = &(SLockArray[lockid]);
+ SLock *slckP;
+
+ slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
- printf("ExclusiveUnlock(%d)\n", lockid);
- printf("IN: ");
- PRINT_LOCK(slckP);
+ printf("ExclusiveUnlock(%d)\n", lockid);
+ printf("IN: ");
+ PRINT_LOCK(slckP);
#endif
- S_LOCK(&(slckP->locklock));
- /* -------------
- * give favor to read processes
- * -------------
- */
- slckP->flag = NOLOCK;
- if (slckP->nshlocks > 0) {
- while (slckP->nshlocks > 0) {
- S_UNLOCK(&(slckP->shlock));
- S_LOCK(&(slckP->comlock));
+ S_LOCK(&(slckP->locklock));
+ /* -------------
+ * give favor to read processes
+ * -------------
+ */
+ slckP->flag = NOLOCK;
+ if (slckP->nshlocks > 0)
+ {
+ while (slckP->nshlocks > 0)
+ {
+ S_UNLOCK(&(slckP->shlock));
+ S_LOCK(&(slckP->comlock));
+ }
+ S_UNLOCK(&(slckP->shlock));
}
- S_UNLOCK(&(slckP->shlock));
- }
- else {
- S_UNLOCK(&(slckP->shlock));
- }
- S_UNLOCK(&(slckP->exlock));
- S_UNLOCK(&(slckP->locklock));
+ else
+ {
+ S_UNLOCK(&(slckP->shlock));
+ }
+ S_UNLOCK(&(slckP->exlock));
+ S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
- printf("OUT: ");
- PRINT_LOCK(slckP);
+ printf("OUT: ");
+ PRINT_LOCK(slckP);
#endif
- return;
+ return;
}
bool
LockIsFree(int lockid)
{
- return(SLockArray[lockid].flag == NOLOCK);
+ return (SLockArray[lockid].flag == NOLOCK);
}
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
static void
IpcConfigTip(void)
{
- fprintf(stderr,"This type of error is usually caused by improper\n");
- fprintf(stderr,"shared memory or System V IPC semaphore configuration.\n");
- fprintf(stderr,"See the FAQ for more detailed information\n");
+ fprintf(stderr, "This type of error is usually caused by improper\n");
+ fprintf(stderr, "shared memory or System V IPC semaphore configuration.\n");
+ fprintf(stderr, "See the FAQ for more detailed information\n");
}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index f949041f44d..4aad8e85f54 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* ipci.c--
- * POSTGRES inter-process communication initialization code.
+ * POSTGRES inter-process communication initialization code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.5 1997/01/08 08:32:03 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.6 1997/09/07 04:48:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,129 +23,131 @@
#include "storage/proc.h"
#include "storage/smgr.h"
#include "storage/lock.h"
-#include "miscadmin.h" /* for DebugLvl */
+#include "miscadmin.h" /* for DebugLvl */
/*
* SystemPortAddressCreateMemoryKey --
- * Returns a memory key given a port address.
+ * Returns a memory key given a port address.
*/
IPCKey
SystemPortAddressCreateIPCKey(SystemPortAddress address)
{
- Assert(address < 32768); /* XXX */
-
- return (SystemPortAddressGetIPCKey(address));
+ Assert(address < 32768); /* XXX */
+
+ return (SystemPortAddressGetIPCKey(address));
}
/*
* CreateSharedMemoryAndSemaphores --
- * Creates and initializes shared memory and semaphores.
+ * Creates and initializes shared memory and semaphores.
*/
/**************************************************
-
+
CreateSharedMemoryAndSemaphores
is called exactly *ONCE* by the postmaster.
It is *NEVER* called by the postgres backend
-
+
0) destroy any existing semaphores for both buffer
and lock managers.
1) create the appropriate *SHARED* memory segments
for the two resource managers.
-
+
**************************************************/
void
CreateSharedMemoryAndSemaphores(IPCKey key)
{
- int size;
-
+ int size;
+
#ifdef HAS_TEST_AND_SET
- /* ---------------
- * create shared memory for slocks
- * --------------
- */
- CreateAndInitSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
+ /* ---------------
+ * create shared memory for slocks
+ * --------------
+ */
+ CreateAndInitSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
#endif
- /* ----------------
- * kill and create the buffer manager buffer pool (and semaphore)
- * ----------------
- */
- CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
- size = BufferShmemSize() + LockShmemSize();
-
+ /* ----------------
+ * kill and create the buffer manager buffer pool (and semaphore)
+ * ----------------
+ */
+ CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
+ size = BufferShmemSize() + LockShmemSize();
+
#ifdef MAIN_MEMORY
- size += MMShmemSize();
-#endif /* MAIN_MEMORY */
-
- if (DebugLvl > 1) {
- fprintf(stderr, "binding ShmemCreate(key=%x, size=%d)\n",
- IPCKeyGetBufferMemoryKey(key), size);
- }
- ShmemCreate(IPCKeyGetBufferMemoryKey(key), size);
- ShmemBindingTabReset();
- InitShmem(key, size);
- InitBufferPool(key);
-
- /* ----------------
- * do the lock table stuff
- * ----------------
- */
- InitLocks();
- InitMultiLevelLockm();
- if (InitMultiLevelLockm() == INVALID_TABLEID)
- elog(FATAL, "Couldn't create the lock table");
-
- /* ----------------
- * do process table stuff
- * ----------------
- */
- InitProcGlobal(key);
- on_exitpg(ProcFreeAllSemaphores, 0);
-
- CreateSharedInvalidationState(key);
+ size += MMShmemSize();
+#endif /* MAIN_MEMORY */
+
+ if (DebugLvl > 1)
+ {
+ fprintf(stderr, "binding ShmemCreate(key=%x, size=%d)\n",
+ IPCKeyGetBufferMemoryKey(key), size);
+ }
+ ShmemCreate(IPCKeyGetBufferMemoryKey(key), size);
+ ShmemBindingTabReset();
+ InitShmem(key, size);
+ InitBufferPool(key);
+
+ /* ----------------
+ * do the lock table stuff
+ * ----------------
+ */
+ InitLocks();
+ InitMultiLevelLockm();
+ if (InitMultiLevelLockm() == INVALID_TABLEID)
+ elog(FATAL, "Couldn't create the lock table");
+
+ /* ----------------
+ * do process table stuff
+ * ----------------
+ */
+ InitProcGlobal(key);
+ on_exitpg(ProcFreeAllSemaphores, 0);
+
+ CreateSharedInvalidationState(key);
}
/*
* AttachSharedMemoryAndSemaphores --
- * Attachs existant shared memory and semaphores.
+ * Attachs existant shared memory and semaphores.
*/
void
AttachSharedMemoryAndSemaphores(IPCKey key)
{
- int size;
-
- /* ----------------
- * create rather than attach if using private key
- * ----------------
- */
- if (key == PrivateIPCKey) {
- CreateSharedMemoryAndSemaphores(key);
- return;
- }
-
+ int size;
+
+ /* ----------------
+ * create rather than attach if using private key
+ * ----------------
+ */
+ if (key == PrivateIPCKey)
+ {
+ CreateSharedMemoryAndSemaphores(key);
+ return;
+ }
+
#ifdef HAS_TEST_AND_SET
- /* ----------------
- * attach the slock shared memory
- * ----------------
- */
- AttachSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
+ /* ----------------
+ * attach the slock shared memory
+ * ----------------
+ */
+ AttachSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
#endif
- /* ----------------
- * attach the buffer manager buffer pool (and semaphore)
- * ----------------
- */
- size = BufferShmemSize() + LockShmemSize();
- InitShmem(key, size);
- InitBufferPool(key);
-
- /* ----------------
- * initialize lock table stuff
- * ----------------
- */
- InitLocks();
- if (InitMultiLevelLockm() == INVALID_TABLEID)
- elog(FATAL, "Couldn't attach to the lock table");
-
- AttachSharedInvalidationState(key);
+ /* ----------------
+ * attach the buffer manager buffer pool (and semaphore)
+ * ----------------
+ */
+ size = BufferShmemSize() + LockShmemSize();
+ InitShmem(key, size);
+ InitBufferPool(key);
+
+ /* ----------------
+ * initialize lock table stuff
+ * ----------------
+ */
+ InitLocks();
+ if (InitMultiLevelLockm() == INVALID_TABLEID)
+ elog(FATAL, "Couldn't attach to the lock table");
+
+ AttachSharedInvalidationState(key);
}
diff --git a/src/backend/storage/ipc/s_lock.c b/src/backend/storage/ipc/s_lock.c
index 146c2d7080a..70f0deb62c9 100644
--- a/src/backend/storage/ipc/s_lock.c
+++ b/src/backend/storage/ipc/s_lock.c
@@ -1,40 +1,40 @@
/*-------------------------------------------------------------------------
*
* s_lock.c--
- * This file contains the implementation (if any) for spinlocks.
+ * This file contains the implementation (if any) for spinlocks.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/s_lock.c,v 1.21 1997/09/05 18:10:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/s_lock.c,v 1.22 1997/09/07 04:48:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * DESCRIPTION
- * The following code fragment should be written (in assembly
- * language) on machines that have a native test-and-set instruction:
+ * DESCRIPTION
+ * The following code fragment should be written (in assembly
+ * language) on machines that have a native test-and-set instruction:
*
- * void
- * S_LOCK(char_address)
- * char *char_address;
- * {
- * while (test_and_set(char_address))
- * ;
- * }
+ * void
+ * S_LOCK(char_address)
+ * char *char_address;
+ * {
+ * while (test_and_set(char_address))
+ * ;
+ * }
*
- * If this is not done, POSTGRES will default to using System V
- * semaphores (and take a large performance hit -- around 40% of
- * its time on a DS5000/240 is spent in semop(3)...).
+ * If this is not done, POSTGRES will default to using System V
+ * semaphores (and take a large performance hit -- around 40% of
+ * its time on a DS5000/240 is spent in semop(3)...).
*
- * NOTES
- * AIX has a test-and-set but the recommended interface is the cs(3)
- * system call. This provides an 8-instruction (plus system call
- * overhead) uninterruptible compare-and-set operation. True
- * spinlocks might be faster but using cs(3) still speeds up the
- * regression test suite by about 25%. I don't have an assembler
- * manual for POWER in any case.
+ * NOTES
+ * AIX has a test-and-set but the recommended interface is the cs(3)
+ * system call. This provides an 8-instruction (plus system call
+ * overhead) uninterruptible compare-and-set operation. True
+ * spinlocks might be faster but using cs(3) still speeds up the
+ * regression test suite by about 25%. I don't have an assembler
+ * manual for POWER in any case.
*
*/
#include "postgres.h"
@@ -50,71 +50,71 @@
* slock_t is defined as a struct mutex.
*/
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
mutex_lock(lock);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
mutex_unlock(lock);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- mutex_init(lock);
+ mutex_init(lock);
}
/* S_LOCK_FREE should return 1 if lock is free; 0 if lock is locked */
int
- S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
/* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */
- return (lock->lock == 0);
+ return (lock->lock == 0);
}
-#endif /* next */
+#endif /* next */
#if defined(irix5)
/*
* SGI IRIX 5
- * slock_t is defined as a struct abilock_t, which has a single unsigned long
+ * slock_t is defined as a struct abilock_t, which has a single unsigned long
* member.
- *
+ *
* This stuff may be supplemented in the future with Masato Kataoka's MIPS-II
* assembly from his NECEWS SVR4 port, but we probably ought to retain this
* for the R3000 chips out there.
*/
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
/* spin_lock(lock); */
while (!acquire_lock(lock))
- ;
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
release_lock(lock);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- init_lock(lock);
+ init_lock(lock);
}
/* S_LOCK_FREE should return 1 if lock is free; 0 if lock is locked */
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- return(stat_lock(lock)==UNLOCKED);
+ return (stat_lock(lock) == UNLOCKED);
}
-#endif /* irix5 */
+#endif /* irix5 */
/*
@@ -127,62 +127,62 @@ S_LOCK_FREE(slock_t *lock)
#if defined(__alpha__) || defined(__alpha)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (msem_lock(lock, MSEM_IF_NOWAIT) < 0)
- ;
+ while (msem_lock(lock, MSEM_IF_NOWAIT) < 0)
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- msem_unlock(lock, 0);
+ msem_unlock(lock, 0);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- msem_init(lock, MSEM_UNLOCKED);
+ msem_init(lock, MSEM_UNLOCKED);
}
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- return(lock->msem_state ? 0 : 1);
+ return (lock->msem_state ? 0 : 1);
}
-#endif /* alpha */
+#endif /* alpha */
/*
* Solaris 2
*/
#if defined(i386_solaris) || \
- defined(sparc_solaris)
+ defined(sparc_solaris)
/* for xxxxx_solaris, this is defined in port/.../tas.s */
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* i86pc_solaris || sparc_solaris */
+#endif /* i86pc_solaris || sparc_solaris */
/*
* AIX (POWER)
@@ -194,25 +194,25 @@ S_INIT_LOCK(slock_t *lock)
#if defined(aix)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (cs((int *) lock, 0, 1))
- ;
+ while (cs((int *) lock, 0, 1))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* aix */
+#endif /* aix */
/*
* HP-UX (PA-RISC)
@@ -224,90 +224,90 @@ S_INIT_LOCK(slock_t *lock)
#if defined(hpux)
/*
-* a "set" slock_t has a single word cleared. a "clear" slock_t has
+* a "set" slock_t has a single word cleared. a "clear" slock_t has
* all words set to non-zero.
*/
-static slock_t clear_lock = { -1, -1, -1, -1 };
+static slock_t clear_lock = {-1, -1, -1, -1};
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = clear_lock; /* struct assignment */
+ *lock = clear_lock; /* struct assignment */
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- register int *lock_word = (int *) (((long) lock + 15) & ~15);
+ register int *lock_word = (int *) (((long) lock + 15) & ~15);
- return(*lock_word != 0);
+ return (*lock_word != 0);
}
-#endif /* hpux */
+#endif /* hpux */
/*
* sun3
*/
-
+
#if defined(sun3)
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
-void
-S_LOCK(slock_t *lock)
+void
+S_LOCK(slock_t * lock)
{
- while (tas(lock));
+ while (tas(lock));
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
static int
tas_dummy()
{
- asm("LLA0:");
- asm(" .data");
- asm(" .text");
- asm("|#PROC# 04");
- asm(" .globl _tas");
- asm("_tas:");
- asm("|#PROLOGUE# 1");
- asm(" movel sp@(0x4),a0");
- asm(" tas a0@");
- asm(" beq LLA1");
- asm(" moveq #-128,d0");
- asm(" rts");
- asm("LLA1:");
- asm(" moveq #0,d0");
- asm(" rts");
- asm(" .data");
-}
-
-#endif /* sun3 */
+ asm("LLA0:");
+ asm(" .data");
+ asm(" .text");
+ asm("|#PROC# 04");
+ asm(" .globl _tas");
+ asm("_tas:");
+ asm("|#PROLOGUE# 1");
+ asm(" movel sp@(0x4),a0");
+ asm(" tas a0@");
+ asm(" beq LLA1");
+ asm(" moveq #-128,d0");
+ asm(" rts");
+ asm("LLA1:");
+ asm(" moveq #0,d0");
+ asm(" rts");
+ asm(" .data");
+}
+
+#endif /* sun3 */
/*
* sparc machines
@@ -317,48 +317,48 @@ tas_dummy()
/* if we're using -ansi w/ gcc, use __asm__ instead of asm */
#if defined(__STRICT_ANSI__)
-#define asm(x) __asm__(x)
-#endif
+#define asm(x) __asm__(x)
+#endif
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
static int
tas_dummy()
{
- asm(".seg \"data\"");
- asm(".seg \"text\"");
- asm(".global _tas");
- asm("_tas:");
-
- /*
- * Sparc atomic test and set (sparc calls it "atomic load-store")
- */
-
- asm("ldstub [%r8], %r8");
-
- /*
- * Did test and set actually do the set?
- */
-
- asm("tst %r8");
-
- asm("be,a ReturnZero");
-
- /*
- * otherwise, just return.
- */
-
- asm("clr %r8");
- asm("mov 0x1, %r8");
- asm("ReturnZero:");
- asm("retl");
- asm("nop");
+ asm(".seg \"data\"");
+ asm(".seg \"text\"");
+ asm(".global _tas");
+ asm("_tas:");
+
+ /*
+ * Sparc atomic test and set (sparc calls it "atomic load-store")
+ */
+
+ asm("ldstub [%r8], %r8");
+
+ /*
+ * Did test and set actually do the set?
+ */
+
+ asm("tst %r8");
+
+ asm("be,a ReturnZero");
+
+ /*
+ * otherwise, just return.
+ */
+
+ asm("clr %r8");
+ asm("mov 0x1, %r8");
+ asm("ReturnZero:");
+ asm("retl");
+ asm("nop");
}
void
S_LOCK(unsigned char *addr)
{
- while (tas(addr));
+ while (tas(addr));
}
@@ -368,16 +368,16 @@ S_LOCK(unsigned char *addr)
void
S_UNLOCK(unsigned char *addr)
{
- *addr = 0;
+ *addr = 0;
}
void
S_INIT_LOCK(unsigned char *addr)
{
- *addr = 0;
+ *addr = 0;
}
-#endif /* NEED_SPARC_TAS_ASM */
+#endif /* NEED_SPARC_TAS_ASM */
/*
* i386 based things
@@ -386,39 +386,41 @@ S_INIT_LOCK(unsigned char *addr)
#if defined(NEED_I386_TAS_ASM)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__("xchgb %0,%1":"=q" (res),"=m" (*lock):"0" (0x1));
- }while(res != 0);
+ do
+ {
+__asm__("xchgb %0,%1": "=q"(res), "=m"(*lock):"0"(0x1));
+ } while (res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* NEED_I386_TAS_ASM */
+#endif /* NEED_I386_TAS_ASM */
#if defined(__alpha__) && defined(linux)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__(" ldq $0, %0 \n\
+ do
+ {
+__asm__(" ldq $0, %0 \n\
bne $0, already_set \n\
ldq_l $0, %0 \n\
bne $0, already_set \n\
@@ -430,56 +432,58 @@ S_LOCK(slock_t *lock)
jmp $31, end \n\
stqc_fail: or $31, 1, $0 \n\
already_set: bis $0, $0, %1 \n\
- end: nop " : "=m" (*lock), "=r" (res) :: "0" );
- }while(res != 0);
+ end: nop ": "=m"(*lock), "=r"(res): :"0");
+ } while (res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- __asm__("mb");
- *lock = 0;
+ __asm__("mb");
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(__alpha__) && defined(linux) */
+#endif /* defined(__alpha__) && defined(linux) */
#if defined(linux) && defined(sparc)
-
+
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__("ldstub [%1], %0"
- : "=&r" (res)
- : "r" (lock));
- }while(!res != 0);
+ do
+ {
+ __asm__("ldstub [%1], %0"
+: "=&r"(res)
+: "r"(lock));
+ } while (!res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(linux) && defined(sparc) */
+#endif /* defined(linux) && defined(sparc) */
#if defined(linux) && defined(PPC)
-static int tas_dummy()
+static int
+tas_dummy()
{
__asm__(" \n\
tas: \n\
@@ -496,26 +500,26 @@ success: \n\
blr \n\
");
}
-
+
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(linux) && defined(PPC) */
+#endif /* defined(linux) && defined(PPC) */
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index c839059ea9b..63848171a1f 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* shmem.c--
- * create shared memory and initialize shared memory data structures.
+ * create shared memory and initialize shared memory data structures.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.10 1997/08/12 22:53:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.11 1997/09/07 04:48:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,43 +18,43 @@
* allocating and binding to shared memory data structures.
*
* NOTES:
- * (a) There are three kinds of shared memory data structures
- * available to POSTGRES: fixed-size structures, queues and hash
- * tables. Fixed-size structures contain things like global variables
- * for a module and should never be allocated after the process
- * initialization phase. Hash tables have a fixed maximum size, but
- * their actual size can vary dynamically. When entries are added
- * to the table, more space is allocated. Queues link data structures
- * that have been allocated either as fixed size structures or as hash
- * buckets. Each shared data structure has a string name to identify
- * it (assigned in the module that declares it).
+ * (a) There are three kinds of shared memory data structures
+ * available to POSTGRES: fixed-size structures, queues and hash
+ * tables. Fixed-size structures contain things like global variables
+ * for a module and should never be allocated after the process
+ * initialization phase. Hash tables have a fixed maximum size, but
+ * their actual size can vary dynamically. When entries are added
+ * to the table, more space is allocated. Queues link data structures
+ * that have been allocated either as fixed size structures or as hash
+ * buckets. Each shared data structure has a string name to identify
+ * it (assigned in the module that declares it).
*
- * (b) During initialization, each module looks for its
- * shared data structures in a hash table called the "Binding Table".
- * If the data structure is not present, the caller can allocate
- * a new one and initialize it. If the data structure is present,
- * the caller "attaches" to the structure by initializing a pointer
- * in the local address space.
- * The binding table has two purposes: first, it gives us
- * a simple model of how the world looks when a backend process
- * initializes. If something is present in the binding table,
- * it is initialized. If it is not, it is uninitialized. Second,
- * the binding table allows us to allocate shared memory on demand
- * instead of trying to preallocate structures and hard-wire the
- * sizes and locations in header files. If you are using a lot
- * of shared memory in a lot of different places (and changing
- * things during development), this is important.
+ * (b) During initialization, each module looks for its
+ * shared data structures in a hash table called the "Binding Table".
+ * If the data structure is not present, the caller can allocate
+ * a new one and initialize it. If the data structure is present,
+ * the caller "attaches" to the structure by initializing a pointer
+ * in the local address space.
+ * The binding table has two purposes: first, it gives us
+ * a simple model of how the world looks when a backend process
+ * initializes. If something is present in the binding table,
+ * it is initialized. If it is not, it is uninitialized. Second,
+ * the binding table allows us to allocate shared memory on demand
+ * instead of trying to preallocate structures and hard-wire the
+ * sizes and locations in header files. If you are using a lot
+ * of shared memory in a lot of different places (and changing
+ * things during development), this is important.
*
- * (c) memory allocation model: shared memory can never be
- * freed, once allocated. Each hash table has its own free list,
- * so hash buckets can be reused when an item is deleted. However,
- * if one hash table grows very large and then shrinks, its space
- * cannot be redistributed to other tables. We could build a simple
- * hash bucket garbage collector if need be. Right now, it seems
- * unnecessary.
+ * (c) memory allocation model: shared memory can never be
+ * freed, once allocated. Each hash table has its own free list,
+ * so hash buckets can be reused when an item is deleted. However,
+ * if one hash table grows very large and then shrinks, its space
+ * cannot be redistributed to other tables. We could build a simple
+ * hash bucket garbage collector if need be. Right now, it seems
+ * unnecessary.
*
- * See InitSem() in sem.c for an example of how to use the
- * binding table.
+ * See InitSem() in sem.c for an example of how to use the
+ * binding table.
*
*/
#include <stdio.h>
@@ -70,27 +70,23 @@
/* shared memory global variables */
-unsigned long ShmemBase = 0; /* start and end address of
- * shared memory
- */
-static unsigned long ShmemEnd = 0;
-static unsigned long ShmemSize = 0; /* current size (and default) */
+unsigned long ShmemBase = 0; /* start and end address of shared memory */
+static unsigned long ShmemEnd = 0;
+static unsigned long ShmemSize = 0; /* current size (and default) */
-SPINLOCK ShmemLock; /* lock for shared memory allocation */
+SPINLOCK ShmemLock; /* lock for shared memory allocation */
-SPINLOCK BindingLock; /* lock for binding table access */
+SPINLOCK BindingLock; /* lock for binding table access */
-static unsigned long *ShmemFreeStart = NULL; /* pointer to the OFFSET of
- * first free shared memory
- */
-static unsigned long *ShmemBindingTabOffset = NULL; /* start of the binding
- * table (for bootstrap)
- */
-static int ShmemBootstrap = FALSE; /* flag becomes true when shared mem
- * is created by POSTMASTER
- */
+static unsigned long *ShmemFreeStart = NULL; /* pointer to the OFFSET
+ * of first free shared
+ * memory */
+static unsigned long *ShmemBindingTabOffset = NULL; /* start of the binding
+ * table (for bootstrap) */
+static int ShmemBootstrap = FALSE; /* flag becomes true when shared
+ * mem is created by POSTMASTER */
-static HTAB *BindingTable = NULL;
+static HTAB *BindingTable = NULL;
/* ---------------------
* ShmemBindingTabReset() - Resets the binding table to NULL....
@@ -101,16 +97,16 @@ static HTAB *BindingTable = NULL;
void
ShmemBindingTabReset(void)
{
- BindingTable = (HTAB *)NULL;
+ BindingTable = (HTAB *) NULL;
}
/*
- * CreateSharedRegion() --
+ * CreateSharedRegion() --
*
- * This routine is called once by the postmaster to
- * initialize the shared buffer pool. Assume there is
- * only one postmaster so no synchronization is necessary
- * until after this routine completes successfully.
+ * This routine is called once by the postmaster to
+ * initialize the shared buffer pool. Assume there is
+ * only one postmaster so no synchronization is necessary
+ * until after this routine completes successfully.
*
* key is a unique identifier for the shmem region.
* size is the size of the region.
@@ -120,202 +116,220 @@ static IpcMemoryId ShmemId;
void
ShmemCreate(unsigned int key, unsigned int size)
{
- if (size)
- ShmemSize = size;
- /* create shared mem region */
- if ((ShmemId=IpcMemoryCreate(key,ShmemSize,IPCProtection))
- ==IpcMemCreationFailed) {
- elog(FATAL,"ShmemCreate: cannot create region");
- exit(1);
- }
-
- /* ShmemBootstrap is true if shared memory has been
- * created, but not yet initialized. Only the
- * postmaster/creator-of-all-things should have
- * this flag set.
- */
- ShmemBootstrap = TRUE;
+ if (size)
+ ShmemSize = size;
+ /* create shared mem region */
+ if ((ShmemId = IpcMemoryCreate(key, ShmemSize, IPCProtection))
+ == IpcMemCreationFailed)
+ {
+ elog(FATAL, "ShmemCreate: cannot create region");
+ exit(1);
+ }
+
+ /*
+ * ShmemBootstrap is true if shared memory has been created, but not
+ * yet initialized. Only the postmaster/creator-of-all-things should
+ * have this flag set.
+ */
+ ShmemBootstrap = TRUE;
}
/*
- * InitShmem() -- map region into process address space
- * and initialize shared data structures.
+ * InitShmem() -- map region into process address space
+ * and initialize shared data structures.
*
*/
int
InitShmem(unsigned int key, unsigned int size)
{
- Pointer sharedRegion;
- unsigned long currFreeSpace;
-
- HASHCTL info;
- int hash_flags;
- BindingEnt * result,item;
- bool found;
- IpcMemoryId shmid;
-
- /* if zero key, use default memory size */
- if (size)
- ShmemSize = size;
-
- /* default key is 0 */
-
- /* attach to shared memory region (SysV or BSD OS specific) */
- if (ShmemBootstrap && key == PrivateIPCKey)
- /* if we are running backend alone */
- shmid = ShmemId;
- else
- shmid = IpcMemoryIdGet(IPCKeyGetBufferMemoryKey(key), ShmemSize);
- sharedRegion = IpcMemoryAttach(shmid);
- if (sharedRegion == NULL) {
- elog(FATAL,"AttachSharedRegion: couldn't attach to shmem\n");
- return(FALSE);
- }
-
- /* get pointers to the dimensions of shared memory */
- ShmemBase = (unsigned long) sharedRegion;
- ShmemEnd = (unsigned long) sharedRegion + ShmemSize;
- currFreeSpace = 0;
-
- /* First long in shared memory is the count of available space */
- ShmemFreeStart = (unsigned long *) ShmemBase;
- /* next is a shmem pointer to the binding table */
- ShmemBindingTabOffset = ShmemFreeStart + 1;
-
- currFreeSpace +=
- sizeof(ShmemFreeStart) + sizeof(ShmemBindingTabOffset);
-
- /* bootstrap initialize spin locks so we can start to use the
- * allocator and binding table.
- */
- if (! InitSpinLocks(ShmemBootstrap, IPCKeyGetSpinLockSemaphoreKey(key))) {
- return(FALSE);
- }
-
- /* We have just allocated additional space for two spinlocks.
- * Now setup the global free space count
- */
- if (ShmemBootstrap) {
- *ShmemFreeStart = currFreeSpace;
- }
-
- /* if ShmemFreeStart is NULL, then the allocator won't work */
- Assert(*ShmemFreeStart);
-
- /* create OR attach to the shared memory binding table */
- info.keysize = BTABLE_KEYSIZE;
- info.datasize = BTABLE_DATASIZE;
- hash_flags = (HASH_ELEM);
-
- /* This will acquire the binding table lock, but not release it. */
- BindingTable = ShmemInitHash("BindingTable",
- BTABLE_SIZE,BTABLE_SIZE,
- &info,hash_flags);
-
- if (! BindingTable) {
- elog(FATAL,"InitShmem: couldn't initialize Binding Table");
- return(FALSE);
- }
-
- /* Now, check the binding table for an entry to the binding
- * table. If there is an entry there, someone else created
- * the table. Otherwise, we did and we have to initialize it.
- */
- memset(item.key, 0, BTABLE_KEYSIZE);
- strncpy(item.key,"BindingTable",BTABLE_KEYSIZE);
-
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item,HASH_ENTER, &found);
-
-
- if (! result ) {
- elog(FATAL,"InitShmem: corrupted binding table");
- return(FALSE);
- }
-
- if (! found) {
- /* bootstrapping shmem: we have to initialize the
- * binding table now.
+ Pointer sharedRegion;
+ unsigned long currFreeSpace;
+
+ HASHCTL info;
+ int hash_flags;
+ BindingEnt *result,
+ item;
+ bool found;
+ IpcMemoryId shmid;
+
+ /* if zero key, use default memory size */
+ if (size)
+ ShmemSize = size;
+
+ /* default key is 0 */
+
+ /* attach to shared memory region (SysV or BSD OS specific) */
+ if (ShmemBootstrap && key == PrivateIPCKey)
+ /* if we are running backend alone */
+ shmid = ShmemId;
+ else
+ shmid = IpcMemoryIdGet(IPCKeyGetBufferMemoryKey(key), ShmemSize);
+ sharedRegion = IpcMemoryAttach(shmid);
+ if (sharedRegion == NULL)
+ {
+ elog(FATAL, "AttachSharedRegion: couldn't attach to shmem\n");
+ return (FALSE);
+ }
+
+ /* get pointers to the dimensions of shared memory */
+ ShmemBase = (unsigned long) sharedRegion;
+ ShmemEnd = (unsigned long) sharedRegion + ShmemSize;
+ currFreeSpace = 0;
+
+ /* First long in shared memory is the count of available space */
+ ShmemFreeStart = (unsigned long *) ShmemBase;
+ /* next is a shmem pointer to the binding table */
+ ShmemBindingTabOffset = ShmemFreeStart + 1;
+
+ currFreeSpace +=
+ sizeof(ShmemFreeStart) + sizeof(ShmemBindingTabOffset);
+
+ /*
+ * bootstrap initialize spin locks so we can start to use the
+ * allocator and binding table.
*/
-
- Assert(ShmemBootstrap);
- result->location = MAKE_OFFSET(BindingTable->hctl);
- *ShmemBindingTabOffset = result->location;
- result->size = BTABLE_SIZE;
-
- ShmemBootstrap = FALSE;
-
- } else {
- Assert(! ShmemBootstrap);
- }
- /* now release the lock acquired in ShmemHashInit */
- SpinRelease (BindingLock);
-
- Assert (result->location == MAKE_OFFSET(BindingTable->hctl));
-
- return(TRUE);
+ if (!InitSpinLocks(ShmemBootstrap, IPCKeyGetSpinLockSemaphoreKey(key)))
+ {
+ return (FALSE);
+ }
+
+ /*
+ * We have just allocated additional space for two spinlocks. Now
+ * setup the global free space count
+ */
+ if (ShmemBootstrap)
+ {
+ *ShmemFreeStart = currFreeSpace;
+ }
+
+ /* if ShmemFreeStart is NULL, then the allocator won't work */
+ Assert(*ShmemFreeStart);
+
+ /* create OR attach to the shared memory binding table */
+ info.keysize = BTABLE_KEYSIZE;
+ info.datasize = BTABLE_DATASIZE;
+ hash_flags = (HASH_ELEM);
+
+ /* This will acquire the binding table lock, but not release it. */
+ BindingTable = ShmemInitHash("BindingTable",
+ BTABLE_SIZE, BTABLE_SIZE,
+ &info, hash_flags);
+
+ if (!BindingTable)
+ {
+ elog(FATAL, "InitShmem: couldn't initialize Binding Table");
+ return (FALSE);
+ }
+
+ /*
+ * Now, check the binding table for an entry to the binding table. If
+ * there is an entry there, someone else created the table.
+ * Otherwise, we did and we have to initialize it.
+ */
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ strncpy(item.key, "BindingTable", BTABLE_KEYSIZE);
+
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, &found);
+
+
+ if (!result)
+ {
+ elog(FATAL, "InitShmem: corrupted binding table");
+ return (FALSE);
+ }
+
+ if (!found)
+ {
+
+ /*
+ * bootstrapping shmem: we have to initialize the binding table
+ * now.
+ */
+
+ Assert(ShmemBootstrap);
+ result->location = MAKE_OFFSET(BindingTable->hctl);
+ *ShmemBindingTabOffset = result->location;
+ result->size = BTABLE_SIZE;
+
+ ShmemBootstrap = FALSE;
+
+ }
+ else
+ {
+ Assert(!ShmemBootstrap);
+ }
+ /* now release the lock acquired in ShmemHashInit */
+ SpinRelease(BindingLock);
+
+ Assert(result->location == MAKE_OFFSET(BindingTable->hctl));
+
+ return (TRUE);
}
/*
* ShmemAlloc -- allocate word-aligned byte string from
- * shared memory
+ * shared memory
*
* Assumes ShmemLock and ShmemFreeStart are initialized.
* Returns: real pointer to memory or NULL if we are out
- * of space. Has to return a real pointer in order
- * to be compatable with malloc().
+ * of space. Has to return a real pointer in order
+ * to be compatable with malloc().
*/
-long *
+long *
ShmemAlloc(unsigned long size)
{
- unsigned long tmpFree;
- long *newSpace;
-
- /*
- * ensure space is word aligned.
- *
- * Word-alignment is not good enough. We have to be more
- * conservative: doubles need 8-byte alignment. (We probably only need
- * this on RISC platforms but this is not a big waste of space.)
- * - ay 12/94
- */
- if (size % sizeof(double))
- size += sizeof(double) - (size % sizeof(double));
-
- Assert(*ShmemFreeStart);
-
- SpinAcquire(ShmemLock);
-
- tmpFree = *ShmemFreeStart + size;
- if (tmpFree <= ShmemSize) {
- newSpace = (long *)MAKE_PTR(*ShmemFreeStart);
- *ShmemFreeStart += size;
- } else {
- newSpace = NULL;
- }
-
- SpinRelease(ShmemLock);
-
- if (! newSpace) {
- elog(NOTICE,"ShmemAlloc: out of memory ");
- }
- return(newSpace);
+ unsigned long tmpFree;
+ long *newSpace;
+
+ /*
+ * ensure space is word aligned.
+ *
+ * Word-alignment is not good enough. We have to be more conservative:
+ * doubles need 8-byte alignment. (We probably only need this on RISC
+ * platforms but this is not a big waste of space.) - ay 12/94
+ */
+ if (size % sizeof(double))
+ size += sizeof(double) - (size % sizeof(double));
+
+ Assert(*ShmemFreeStart);
+
+ SpinAcquire(ShmemLock);
+
+ tmpFree = *ShmemFreeStart + size;
+ if (tmpFree <= ShmemSize)
+ {
+ newSpace = (long *) MAKE_PTR(*ShmemFreeStart);
+ *ShmemFreeStart += size;
+ }
+ else
+ {
+ newSpace = NULL;
+ }
+
+ SpinRelease(ShmemLock);
+
+ if (!newSpace)
+ {
+ elog(NOTICE, "ShmemAlloc: out of memory ");
+ }
+ return (newSpace);
}
/*
- * ShmemIsValid -- test if an offset refers to valid shared memory
- *
+ * ShmemIsValid -- test if an offset refers to valid shared memory
+ *
* Returns TRUE if the pointer is valid.
*/
int
ShmemIsValid(unsigned long addr)
{
- return ((addr<ShmemEnd) && (addr>=ShmemBase));
+ return ((addr < ShmemEnd) && (addr >= ShmemBase));
}
/*
- * ShmemInitHash -- Create/Attach to and initialize
- * shared memory hash table.
+ * ShmemInitHash -- Create/Attach to and initialize
+ * shared memory hash table.
*
* Notes:
*
@@ -324,281 +338,308 @@ ShmemIsValid(unsigned long addr)
* table at once. Use SpinAlloc() to create a spinlock
* for the structure before creating the structure itself.
*/
-HTAB *
-ShmemInitHash(char *name, /* table string name for binding */
- long init_size, /* initial size */
- long max_size, /* max size of the table */
- HASHCTL *infoP, /* info about key and bucket size */
- int hash_flags) /* info about infoP */
+HTAB *
+ShmemInitHash(char *name, /* table string name for binding */
+ long init_size, /* initial size */
+ long max_size, /* max size of the table */
+ HASHCTL * infoP, /* info about key and bucket size */
+ int hash_flags) /* info about infoP */
{
- bool found;
- long * location;
-
- /* shared memory hash tables have a fixed max size so that the
- * control structures don't try to grow. The segbase is for
- * calculating pointer values. The shared memory allocator
- * must be specified.
- */
- infoP->segbase = (long *) ShmemBase;
- infoP->alloc = ShmemAlloc;
- infoP->max_size = max_size;
- hash_flags |= HASH_SHARED_MEM;
-
- /* look it up in the binding table */
- location =
- ShmemInitStruct(name,my_log2(max_size) + sizeof(HHDR),&found);
-
- /* binding table is corrupted. Let someone else give the
- * error message since they have more information
- */
- if (location == NULL) {
- return(0);
- }
-
- /* it already exists, attach to it rather than allocate and
- * initialize new space
- */
- if (found) {
- hash_flags |= HASH_ATTACH;
- }
-
- /* these structures were allocated or bound in ShmemInitStruct */
- /* control information and parameters */
- infoP->hctl = (long *) location;
- /* directory for hash lookup */
- infoP->dir = (long *) (location + sizeof(HHDR));
-
- return(hash_create(init_size, infoP, hash_flags));;
+ bool found;
+ long *location;
+
+ /*
+ * shared memory hash tables have a fixed max size so that the control
+ * structures don't try to grow. The segbase is for calculating
+ * pointer values. The shared memory allocator must be specified.
+ */
+ infoP->segbase = (long *) ShmemBase;
+ infoP->alloc = ShmemAlloc;
+ infoP->max_size = max_size;
+ hash_flags |= HASH_SHARED_MEM;
+
+ /* look it up in the binding table */
+ location =
+ ShmemInitStruct(name, my_log2(max_size) + sizeof(HHDR), &found);
+
+ /*
+ * binding table is corrupted. Let someone else give the error
+ * message since they have more information
+ */
+ if (location == NULL)
+ {
+ return (0);
+ }
+
+ /*
+ * it already exists, attach to it rather than allocate and initialize
+ * new space
+ */
+ if (found)
+ {
+ hash_flags |= HASH_ATTACH;
+ }
+
+ /* these structures were allocated or bound in ShmemInitStruct */
+ /* control information and parameters */
+ infoP->hctl = (long *) location;
+ /* directory for hash lookup */
+ infoP->dir = (long *) (location + sizeof(HHDR));
+
+ return (hash_create(init_size, infoP, hash_flags));;
}
/*
* ShmemPIDLookup -- lookup process data structure using process id
*
* Returns: TRUE if no error. locationPtr is initialized if PID is
- * found in the binding table.
+ * found in the binding table.
*
* NOTES:
- * only information about success or failure is the value of
- * locationPtr.
+ * only information about success or failure is the value of
+ * locationPtr.
*/
bool
-ShmemPIDLookup(int pid, SHMEM_OFFSET* locationPtr)
+ShmemPIDLookup(int pid, SHMEM_OFFSET * locationPtr)
{
- BindingEnt * result,item;
- bool found;
-
- Assert (BindingTable);
- memset(item.key, 0, BTABLE_KEYSIZE);
- sprintf(item.key,"PID %d",pid);
-
- SpinAcquire(BindingLock);
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item, HASH_ENTER, &found);
-
- if (! result) {
-
+ BindingEnt *result,
+ item;
+ bool found;
+
+ Assert(BindingTable);
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ sprintf(item.key, "PID %d", pid);
+
+ SpinAcquire(BindingLock);
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, &found);
+
+ if (!result)
+ {
+
+ SpinRelease(BindingLock);
+ elog(WARN, "ShmemInitPID: BindingTable corrupted");
+ return (FALSE);
+
+ }
+
+ if (found)
+ {
+ *locationPtr = result->location;
+ }
+ else
+ {
+ result->location = *locationPtr;
+ }
+
SpinRelease(BindingLock);
- elog(WARN,"ShmemInitPID: BindingTable corrupted");
- return(FALSE);
-
- }
-
- if (found) {
- *locationPtr = result->location;
- } else {
- result->location = *locationPtr;
- }
-
- SpinRelease(BindingLock);
- return (TRUE);
+ return (TRUE);
}
/*
* ShmemPIDDestroy -- destroy binding table entry for process
- * using process id
+ * using process id
*
* Returns: offset of the process struct in shared memory or
- * INVALID_OFFSET if not found.
+ * INVALID_OFFSET if not found.
*
* Side Effect: removes the entry from the binding table
*/
SHMEM_OFFSET
ShmemPIDDestroy(int pid)
{
- BindingEnt * result,item;
- bool found;
- SHMEM_OFFSET location = 0;
-
- Assert(BindingTable);
-
- memset(item.key, 0, BTABLE_KEYSIZE);
- sprintf(item.key,"PID %d",pid);
-
- SpinAcquire(BindingLock);
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item, HASH_REMOVE, &found);
-
- if (found)
- location = result->location;
- SpinRelease(BindingLock);
-
- if (! result) {
-
- elog(WARN,"ShmemPIDDestroy: PID table corrupted");
- return(INVALID_OFFSET);
-
- }
-
- if (found)
- return (location);
- else {
- return(INVALID_OFFSET);
- }
+ BindingEnt *result,
+ item;
+ bool found;
+ SHMEM_OFFSET location = 0;
+
+ Assert(BindingTable);
+
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ sprintf(item.key, "PID %d", pid);
+
+ SpinAcquire(BindingLock);
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_REMOVE, &found);
+
+ if (found)
+ location = result->location;
+ SpinRelease(BindingLock);
+
+ if (!result)
+ {
+
+ elog(WARN, "ShmemPIDDestroy: PID table corrupted");
+ return (INVALID_OFFSET);
+
+ }
+
+ if (found)
+ return (location);
+ else
+ {
+ return (INVALID_OFFSET);
+ }
}
/*
* ShmemInitStruct -- Create/attach to a structure in shared
- * memory.
+ * memory.
*
- * This is called during initialization to find or allocate
- * a data structure in shared memory. If no other processes
- * have created the structure, this routine allocates space
- * for it. If it exists already, a pointer to the existing
- * table is returned.
+ * This is called during initialization to find or allocate
+ * a data structure in shared memory. If no other processes
+ * have created the structure, this routine allocates space
+ * for it. If it exists already, a pointer to the existing
+ * table is returned.
*
- * Returns: real pointer to the object. FoundPtr is TRUE if
- * the object is already in the binding table (hence, already
- * initialized).
+ * Returns: real pointer to the object. FoundPtr is TRUE if
+ * the object is already in the binding table (hence, already
+ * initialized).
*/
-long *
-ShmemInitStruct(char *name, unsigned long size, bool *foundPtr)
+long *
+ShmemInitStruct(char *name, unsigned long size, bool * foundPtr)
{
- BindingEnt * result,item;
- long * structPtr;
-
- strncpy(item.key,name,BTABLE_KEYSIZE);
- item.location = BAD_LOCATION;
-
- SpinAcquire(BindingLock);
-
- if (! BindingTable) {
- /* Assert() is a macro now. substitutes inside quotes. */
-#ifndef NO_ASSERT_CHECKING
- char *strname = "BindingTable";
+ BindingEnt *result,
+ item;
+ long *structPtr;
+
+ strncpy(item.key, name, BTABLE_KEYSIZE);
+ item.location = BAD_LOCATION;
+
+ SpinAcquire(BindingLock);
+
+ if (!BindingTable)
+ {
+ /* Assert() is a macro now. substitutes inside quotes. */
+#ifndef NO_ASSERT_CHECKING
+ char *strname = "BindingTable";
+
#endif
-
- /* If the binding table doesnt exist, we fake it.
- *
- * If we are creating the first binding table, then let
- * shmemalloc() allocate the space for a new HTAB. Otherwise,
- * find the old one and return that. Notice that the
- * BindingLock is held until the binding table has been completely
- * initialized.
- */
- Assert (! strcmp(name,strname)) ;
- if (ShmemBootstrap) {
- /* in POSTMASTER/Single process */
-
- *foundPtr = FALSE;
- return((long *)ShmemAlloc(size));
-
- } else {
- Assert (ShmemBindingTabOffset);
-
- *foundPtr = TRUE;
- return((long *)MAKE_PTR(*ShmemBindingTabOffset));
+
+ /*
+ * If the binding table doesnt exist, we fake it.
+ *
+ * If we are creating the first binding table, then let shmemalloc()
+ * allocate the space for a new HTAB. Otherwise, find the old one
+ * and return that. Notice that the BindingLock is held until the
+ * binding table has been completely initialized.
+ */
+ Assert(!strcmp(name, strname));
+ if (ShmemBootstrap)
+ {
+ /* in POSTMASTER/Single process */
+
+ *foundPtr = FALSE;
+ return ((long *) ShmemAlloc(size));
+
+ }
+ else
+ {
+ Assert(ShmemBindingTabOffset);
+
+ *foundPtr = TRUE;
+ return ((long *) MAKE_PTR(*ShmemBindingTabOffset));
+ }
+
+
}
-
-
- } else {
- /* look it up in the bindint table */
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item,HASH_ENTER, foundPtr);
- }
-
- if (! result) {
-
- SpinRelease(BindingLock);
-
- elog(WARN,"ShmemInitStruct: Binding Table corrupted");
- return(NULL);
-
- } else if (*foundPtr) {
- /*
- * Structure is in the binding table so someone else has allocated
- * it already. The size better be the same as the size we are
- * trying to initialize to or there is a name conflict (or worse).
- */
- if (result->size != size) {
- SpinRelease(BindingLock);
-
- elog(NOTICE,"ShmemInitStruct: BindingTable entry size is wrong");
- /* let caller print its message too */
- return(NULL);
+ else
+ {
+ /* look it up in the bindint table */
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, foundPtr);
+ }
+
+ if (!result)
+ {
+
+ SpinRelease(BindingLock);
+
+ elog(WARN, "ShmemInitStruct: Binding Table corrupted");
+ return (NULL);
+
}
- structPtr = (long *)MAKE_PTR(result->location);
- } else {
-
- /* It isn't in the table yet. allocate and initialize it */
- structPtr = ShmemAlloc((long)size);
- if (! structPtr) {
- /* out of memory */
- Assert (BindingTable);
- hash_search(BindingTable,(char *) &item,HASH_REMOVE, foundPtr);
- SpinRelease(BindingLock);
- *foundPtr = FALSE;
-
- elog(NOTICE,"ShmemInitStruct: cannot allocate '%s'",
- name);
- return(NULL);
- }
- result->size = size;
- result->location = MAKE_OFFSET(structPtr);
- }
- Assert (ShmemIsValid((unsigned long)structPtr));
-
- SpinRelease(BindingLock);
- return(structPtr);
+ else if (*foundPtr)
+ {
+
+ /*
+ * Structure is in the binding table so someone else has allocated
+ * it already. The size better be the same as the size we are
+ * trying to initialize to or there is a name conflict (or worse).
+ */
+ if (result->size != size)
+ {
+ SpinRelease(BindingLock);
+
+ elog(NOTICE, "ShmemInitStruct: BindingTable entry size is wrong");
+ /* let caller print its message too */
+ return (NULL);
+ }
+ structPtr = (long *) MAKE_PTR(result->location);
+ }
+ else
+ {
+
+ /* It isn't in the table yet. allocate and initialize it */
+ structPtr = ShmemAlloc((long) size);
+ if (!structPtr)
+ {
+ /* out of memory */
+ Assert(BindingTable);
+ hash_search(BindingTable, (char *) &item, HASH_REMOVE, foundPtr);
+ SpinRelease(BindingLock);
+ *foundPtr = FALSE;
+
+ elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'",
+ name);
+ return (NULL);
+ }
+ result->size = size;
+ result->location = MAKE_OFFSET(structPtr);
+ }
+ Assert(ShmemIsValid((unsigned long) structPtr));
+
+ SpinRelease(BindingLock);
+ return (structPtr);
}
/*
* TransactionIdIsInProgress -- is given transaction running by some backend
*
- * Strange place for this func, but we have to lookup process data structures
+ * Strange place for this func, but we have to lookup process data structures
* for all running backends. - vadim 11/26/96
*/
bool
-TransactionIdIsInProgress (TransactionId xid)
+TransactionIdIsInProgress(TransactionId xid)
{
- BindingEnt *result;
- PROC *proc;
-
- Assert (BindingTable);
-
- SpinAcquire(BindingLock);
-
- hash_seq ((HTAB *)NULL);
- while ( (result = (BindingEnt *) hash_seq (BindingTable)) != NULL )
- {
- if ( result == (BindingEnt *) TRUE )
- {
- SpinRelease(BindingLock);
- return (false);
- }
- if ( result->location == INVALID_OFFSET ||
- strncmp (result->key, "PID ", 4) != 0 )
- continue;
- proc = (PROC *) MAKE_PTR (result->location);
- if ( proc->xid == xid )
- {
- SpinRelease(BindingLock);
- return (true);
+ BindingEnt *result;
+ PROC *proc;
+
+ Assert(BindingTable);
+
+ SpinAcquire(BindingLock);
+
+ hash_seq((HTAB *) NULL);
+ while ((result = (BindingEnt *) hash_seq(BindingTable)) != NULL)
+ {
+ if (result == (BindingEnt *) TRUE)
+ {
+ SpinRelease(BindingLock);
+ return (false);
+ }
+ if (result->location == INVALID_OFFSET ||
+ strncmp(result->key, "PID ", 4) != 0)
+ continue;
+ proc = (PROC *) MAKE_PTR(result->location);
+ if (proc->xid == xid)
+ {
+ SpinRelease(BindingLock);
+ return (true);
+ }
}
- }
-
- SpinRelease(BindingLock);
- elog (WARN,"TransactionIdIsInProgress: BindingTable corrupted");
- return (false);
-}
+ SpinRelease(BindingLock);
+ elog(WARN, "TransactionIdIsInProgress: BindingTable corrupted");
+ return (false);
+}
diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c
index f727b5719f5..8080fc70208 100644
--- a/src/backend/storage/ipc/shmqueue.c
+++ b/src/backend/storage/ipc/shmqueue.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* shmqueue.c--
- * shared memory linked lists
+ * shared memory linked lists
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.3 1997/08/19 21:33:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.4 1997/09/07 04:48:42 momjian Exp $
*
* NOTES
*
* Package for managing doubly-linked lists in shared memory.
- * The only tricky thing is that SHM_QUEUE will usually be a field
- * in a larger record. SHMQueueGetFirst has to return a pointer
+ * The only tricky thing is that SHM_QUEUE will usually be a field
+ * in a larger record. SHMQueueGetFirst has to return a pointer
* to the record itself instead of a pointer to the SHMQueue field
* of the record. It takes an extra pointer and does some extra
* pointer arithmetic to do this correctly.
@@ -22,178 +22,181 @@
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include "postgres.h"
-#include "storage/shmem.h" /* where the declarations go */
+#include "storage/shmem.h" /* where the declarations go */
/*#define SHMQUEUE_DEBUG*/
#ifdef SHMQUEUE_DEBUG
-#define SHMQUEUE_DEBUG_DEL /* deletions */
-#define SHMQUEUE_DEBUG_HD /* head inserts */
-#define SHMQUEUE_DEBUG_TL /* tail inserts */
+#define SHMQUEUE_DEBUG_DEL /* deletions */
+#define SHMQUEUE_DEBUG_HD /* head inserts */
+#define SHMQUEUE_DEBUG_TL /* tail inserts */
#define SHMQUEUE_DEBUG_ELOG NOTICE
-#endif /* SHMQUEUE_DEBUG */
+#endif /* SHMQUEUE_DEBUG */
/*
* ShmemQueueInit -- make the head of a new queue point
- * to itself
+ * to itself
*/
void
-SHMQueueInit(SHM_QUEUE *queue)
+SHMQueueInit(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- (queue)->prev = (queue)->next = MAKE_OFFSET(queue);
+ Assert(SHM_PTR_VALID(queue));
+ (queue)->prev = (queue)->next = MAKE_OFFSET(queue);
}
/*
* SHMQueueIsDetached -- TRUE if element is not currently
- * in a queue.
+ * in a queue.
*/
#ifdef NOT_USED
bool
-SHMQueueIsDetached(SHM_QUEUE *queue)
+SHMQueueIsDetached(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- return ((queue)->prev == INVALID_OFFSET);
+ Assert(SHM_PTR_VALID(queue));
+ return ((queue)->prev == INVALID_OFFSET);
}
+
#endif
/*
* SHMQueueElemInit -- clear an element's links
*/
void
-SHMQueueElemInit(SHM_QUEUE *queue)
+SHMQueueElemInit(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- (queue)->prev = (queue)->next = INVALID_OFFSET;
+ Assert(SHM_PTR_VALID(queue));
+ (queue)->prev = (queue)->next = INVALID_OFFSET;
}
/*
* SHMQueueDelete -- remove an element from the queue and
- * close the links
+ * close the links
*/
void
-SHMQueueDelete(SHM_QUEUE *queue)
+SHMQueueDelete(SHM_QUEUE * queue)
{
- SHM_QUEUE *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
- SHM_QUEUE *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(nextElem));
- Assert(SHM_PTR_VALID(prevElem));
-
+ SHM_QUEUE *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+ SHM_QUEUE *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(nextElem));
+ Assert(SHM_PTR_VALID(prevElem));
+
#ifdef SHMQUEUE_DEBUG_DEL
- dumpQ(queue, "in SHMQueueDelete: begin");
-#endif /* SHMQUEUE_DEBUG_DEL */
-
- prevElem->next = (queue)->next;
- nextElem->prev = (queue)->prev;
-
+ dumpQ(queue, "in SHMQueueDelete: begin");
+#endif /* SHMQUEUE_DEBUG_DEL */
+
+ prevElem->next = (queue)->next;
+ nextElem->prev = (queue)->prev;
+
#ifdef SHMQUEUE_DEBUG_DEL
- dumpQ((SHM_QUEUE *)MAKE_PTR(queue->prev), "in SHMQueueDelete: end");
-#endif /* SHMQUEUE_DEBUG_DEL */
+ dumpQ((SHM_QUEUE *) MAKE_PTR(queue->prev), "in SHMQueueDelete: end");
+#endif /* SHMQUEUE_DEBUG_DEL */
}
#ifdef SHMQUEUE_DEBUG
void
-dumpQ(SHM_QUEUE *q, char *s)
+dumpQ(SHM_QUEUE * q, char *s)
{
- char elem[16];
- char buf[1024];
- SHM_QUEUE *start = q;
- int count = 0;
-
- sprintf(buf, "q prevs: %x", MAKE_OFFSET(q));
- q = (SHM_QUEUE *)MAKE_PTR(q->prev);
- while (q != start)
+ char elem[16];
+ char buf[1024];
+ SHM_QUEUE *start = q;
+ int count = 0;
+
+ sprintf(buf, "q prevs: %x", MAKE_OFFSET(q));
+ q = (SHM_QUEUE *) MAKE_PTR(q->prev);
+ while (q != start)
{
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- q = (SHM_QUEUE *)MAKE_PTR(q->prev);
- if (q->prev == MAKE_OFFSET(q))
- break;
- if (count++ > 40)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ q = (SHM_QUEUE *) MAKE_PTR(q->prev);
+ if (q->prev == MAKE_OFFSET(q))
+ break;
+ if (count++ > 40)
{
- strcat(buf, "BAD PREV QUEUE!!");
- break;
+ strcat(buf, "BAD PREV QUEUE!!");
+ break;
}
}
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
-
- sprintf(buf, "q nexts: %x", MAKE_OFFSET(q));
- count = 0;
- q = (SHM_QUEUE *)MAKE_PTR(q->next);
- while (q != start)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
+
+ sprintf(buf, "q nexts: %x", MAKE_OFFSET(q));
+ count = 0;
+ q = (SHM_QUEUE *) MAKE_PTR(q->next);
+ while (q != start)
{
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- q = (SHM_QUEUE *)MAKE_PTR(q->next);
- if (q->next == MAKE_OFFSET(q))
- break;
- if (count++ > 10)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ q = (SHM_QUEUE *) MAKE_PTR(q->next);
+ if (q->next == MAKE_OFFSET(q))
+ break;
+ if (count++ > 10)
{
- strcat(buf, "BAD NEXT QUEUE!!");
- break;
+ strcat(buf, "BAD NEXT QUEUE!!");
+ break;
}
}
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
}
-#endif /* SHMQUEUE_DEBUG */
+
+#endif /* SHMQUEUE_DEBUG */
/*
* SHMQueueInsertHD -- put elem in queue between the queue head
- * and its "prev" element.
+ * and its "prev" element.
*/
#ifdef NOT_USED
void
-SHMQueueInsertHD(SHM_QUEUE *queue, SHM_QUEUE *elem)
+SHMQueueInsertHD(SHM_QUEUE * queue, SHM_QUEUE * elem)
{
- SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
- SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(elem));
-
+ SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
+ SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(elem));
+
#ifdef SHMQUEUE_DEBUG_HD
- dumpQ(queue, "in SHMQueueInsertHD: begin");
-#endif /* SHMQUEUE_DEBUG_HD */
-
- (elem)->next = prevPtr->next;
- (elem)->prev = queue->prev;
- (queue)->prev = elemOffset;
- prevPtr->next = elemOffset;
-
+ dumpQ(queue, "in SHMQueueInsertHD: begin");
+#endif /* SHMQUEUE_DEBUG_HD */
+
+ (elem)->next = prevPtr->next;
+ (elem)->prev = queue->prev;
+ (queue)->prev = elemOffset;
+ prevPtr->next = elemOffset;
+
#ifdef SHMQUEUE_DEBUG_HD
- dumpQ(queue, "in SHMQueueInsertHD: end");
-#endif /* SHMQUEUE_DEBUG_HD */
+ dumpQ(queue, "in SHMQueueInsertHD: end");
+#endif /* SHMQUEUE_DEBUG_HD */
}
+
#endif
void
-SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem)
+SHMQueueInsertTL(SHM_QUEUE * queue, SHM_QUEUE * elem)
{
- SHM_QUEUE *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
- SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(elem));
-
+ SHM_QUEUE *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+ SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(elem));
+
#ifdef SHMQUEUE_DEBUG_TL
- dumpQ(queue, "in SHMQueueInsertTL: begin");
-#endif /* SHMQUEUE_DEBUG_TL */
-
- (elem)->prev = nextPtr->prev;
- (elem)->next = queue->next;
- (queue)->next = elemOffset;
- nextPtr->prev = elemOffset;
-
+ dumpQ(queue, "in SHMQueueInsertTL: begin");
+#endif /* SHMQUEUE_DEBUG_TL */
+
+ (elem)->prev = nextPtr->prev;
+ (elem)->next = queue->next;
+ (queue)->next = elemOffset;
+ nextPtr->prev = elemOffset;
+
#ifdef SHMQUEUE_DEBUG_TL
- dumpQ(queue, "in SHMQueueInsertTL: end");
-#endif /* SHMQUEUE_DEBUG_TL */
+ dumpQ(queue, "in SHMQueueInsertTL: end");
+#endif /* SHMQUEUE_DEBUG_TL */
}
/*
@@ -203,52 +206,51 @@ SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem)
* a larger structure, we want to return a pointer to the
* whole structure rather than a pointer to its SHMQueue field.
* I.E. struct {
- * int stuff;
- * SHMQueue elem;
- * } ELEMType;
+ * int stuff;
+ * SHMQueue elem;
+ * } ELEMType;
* when this element is in a queue (queue->next) is struct.elem.
* nextQueue allows us to calculate the offset of the SHMQueue
* field in the structure.
*
* call to SHMQueueFirst should take these parameters:
*
- * &(queueHead),&firstElem,&(firstElem->next)
+ * &(queueHead),&firstElem,&(firstElem->next)
*
* Note that firstElem may well be uninitialized. if firstElem
* is initially K, &(firstElem->next) will be K+ the offset to
* next.
*/
void
-SHMQueueFirst(SHM_QUEUE *queue, Pointer *nextPtrPtr, SHM_QUEUE *nextQueue)
+SHMQueueFirst(SHM_QUEUE * queue, Pointer * nextPtrPtr, SHM_QUEUE * nextQueue)
{
- SHM_QUEUE *elemPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
-
- Assert(SHM_PTR_VALID(queue));
- *nextPtrPtr = (Pointer) (((unsigned long) *nextPtrPtr) +
- ((unsigned long) elemPtr) - ((unsigned long) nextQueue));
-
- /*
- nextPtrPtr a ptr to a structure linked in the queue
- nextQueue is the SHMQueue field of the structure
- *nextPtrPtr - nextQueue is 0 minus the offset of the queue
- field n the record
- elemPtr + (*nextPtrPtr - nexQueue) is the start of the
- structure containing elemPtr.
- */
+ SHM_QUEUE *elemPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+
+ Assert(SHM_PTR_VALID(queue));
+ *nextPtrPtr = (Pointer) (((unsigned long) *nextPtrPtr) +
+ ((unsigned long) elemPtr) - ((unsigned long) nextQueue));
+
+ /*
+ * nextPtrPtr a ptr to a structure linked in the queue nextQueue is
+ * the SHMQueue field of the structure nextPtrPtr - nextQueue is 0
+ * minus the offset of the queue field n the record elemPtr +
+ * (*nextPtrPtr - nexQueue) is the start of the structure containing
+ * elemPtr.
+ */
}
/*
* SHMQueueEmpty -- TRUE if queue head is only element, FALSE otherwise
*/
bool
-SHMQueueEmpty(SHM_QUEUE *queue)
+SHMQueueEmpty(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
-
- if (queue->prev == MAKE_OFFSET(queue))
+ Assert(SHM_PTR_VALID(queue));
+
+ if (queue->prev == MAKE_OFFSET(queue))
{
- Assert(queue->next = MAKE_OFFSET(queue));
- return(TRUE);
+ Assert(queue->next = MAKE_OFFSET(queue));
+ return (TRUE);
}
- return(FALSE);
+ return (FALSE);
}
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index 5f391669113..af16c8a7196 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* sinval.c--
- * POSTGRES shared cache invalidation communication code.
+ * POSTGRES shared cache invalidation communication code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.7 1997/08/12 22:53:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.8 1997/09/07 04:48:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-/* #define INVALIDDEBUG 1 */
+/* #define INVALIDDEBUG 1 */
#include <sys/types.h>
@@ -22,150 +22,156 @@
#include "storage/sinvaladt.h"
#include "storage/spin.h"
-extern SISeg *shmInvalBuffer;/* the shared buffer segment, set by*/
- /* SISegmentAttach() */
-extern BackendId MyBackendId;
-extern BackendTag MyBackendTag;
+extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by */
+
+ /* SISegmentAttach() */
+extern BackendId MyBackendId;
+extern BackendTag MyBackendTag;
SPINLOCK SInvalLock = (SPINLOCK) NULL;
/****************************************************************************/
-/* CreateSharedInvalidationState(key) Create a buffer segment */
-/* */
-/* should be called only by the POSTMASTER */
+/* CreateSharedInvalidationState(key) Create a buffer segment */
+/* */
+/* should be called only by the POSTMASTER */
/****************************************************************************/
void
CreateSharedInvalidationState(IPCKey key)
{
- int status;
-
- /* REMOVED
- SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
- SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
- */
-
- /* SInvalLock gets set in spin.c, during spinlock init */
- status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
-
- if (status == -1) {
- elog(FATAL, "CreateSharedInvalidationState: failed segment init");
- }
+ int status;
+
+ /*
+ * REMOVED SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
+ * SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
+ */
+
+ /* SInvalLock gets set in spin.c, during spinlock init */
+ status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
+
+ if (status == -1)
+ {
+ elog(FATAL, "CreateSharedInvalidationState: failed segment init");
+ }
}
+
/****************************************************************************/
-/* AttachSharedInvalidationState(key) Attach a buffer segment */
-/* */
-/* should be called only by the POSTMASTER */
+/* AttachSharedInvalidationState(key) Attach a buffer segment */
+/* */
+/* should be called only by the POSTMASTER */
/****************************************************************************/
void
AttachSharedInvalidationState(IPCKey key)
{
- int status;
-
- if (key == PrivateIPCKey) {
- CreateSharedInvalidationState(key);
- return;
- }
- /* SInvalLock gets set in spin.c, during spinlock init */
- status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
-
- if (status == -1) {
- elog(FATAL, "AttachSharedInvalidationState: failed segment init");
- }
+ int status;
+
+ if (key == PrivateIPCKey)
+ {
+ CreateSharedInvalidationState(key);
+ return;
+ }
+ /* SInvalLock gets set in spin.c, during spinlock init */
+ status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
+
+ if (status == -1)
+ {
+ elog(FATAL, "AttachSharedInvalidationState: failed segment init");
+ }
}
void
InitSharedInvalidationState(void)
{
- SpinAcquire(SInvalLock);
- if (!SIBackendInit(shmInvalBuffer))
+ SpinAcquire(SInvalLock);
+ if (!SIBackendInit(shmInvalBuffer))
{
- SpinRelease(SInvalLock);
- elog(FATAL, "Backend cache invalidation initialization failed");
+ SpinRelease(SInvalLock);
+ elog(FATAL, "Backend cache invalidation initialization failed");
}
- SpinRelease(SInvalLock);
+ SpinRelease(SInvalLock);
}
/*
* RegisterSharedInvalid --
- * Returns a new local cache invalidation state containing a new entry.
+ * Returns a new local cache invalidation state containing a new entry.
*
* Note:
- * Assumes hash index is valid.
- * Assumes item pointer is valid.
+ * Assumes hash index is valid.
+ * Assumes item pointer is valid.
*/
/****************************************************************************/
-/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
-/* */
-/* register a message in the buffer */
-/* should be called by a backend */
+/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
+/* */
+/* register a message in the buffer */
+/* should be called by a backend */
/****************************************************************************/
void
-RegisterSharedInvalid(int cacheId, /* XXX */
- Index hashIndex,
- ItemPointer pointer)
+RegisterSharedInvalid(int cacheId, /* XXX */
+ Index hashIndex,
+ ItemPointer pointer)
{
- SharedInvalidData newInvalid;
-
- /*
- * This code has been hacked to accept two types of messages. This might
- * be treated more generally in the future.
- *
- * (1)
- * cacheId= system cache id
- * hashIndex= system cache hash index for a (possibly) cached tuple
- * pointer= pointer of (possibly) cached tuple
- *
- * (2)
- * cacheId= special non-syscache id
- * hashIndex= object id contained in (possibly) cached relation descriptor
- * pointer= null
- */
-
- newInvalid.cacheId = cacheId;
- newInvalid.hashIndex = hashIndex;
-
- if (ItemPointerIsValid(pointer)) {
- ItemPointerCopy(pointer, &newInvalid.pointerData);
- } else {
- ItemPointerSetInvalid(&newInvalid.pointerData);
- }
-
- SpinAcquire(SInvalLock);
- if (!SISetDataEntry(shmInvalBuffer, &newInvalid)) {
- /* buffer full */
- /* release a message, mark process cache states to be invalid */
- SISetProcStateInvalid(shmInvalBuffer);
-
- if (!SIDelDataEntry(shmInvalBuffer)) {
- /* inconsistent buffer state -- shd never happen */
- SpinRelease(SInvalLock);
- elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
- }
-
- /* write again */
- SISetDataEntry(shmInvalBuffer, &newInvalid);
- }
- SpinRelease(SInvalLock);
+ SharedInvalidData newInvalid;
+
+ /*
+ * This code has been hacked to accept two types of messages. This
+ * might be treated more generally in the future.
+ *
+ * (1) cacheId= system cache id hashIndex= system cache hash index for a
+ * (possibly) cached tuple pointer= pointer of (possibly) cached tuple
+ *
+ * (2) cacheId= special non-syscache id hashIndex= object id contained in
+ * (possibly) cached relation descriptor pointer= null
+ */
+
+ newInvalid.cacheId = cacheId;
+ newInvalid.hashIndex = hashIndex;
+
+ if (ItemPointerIsValid(pointer))
+ {
+ ItemPointerCopy(pointer, &newInvalid.pointerData);
+ }
+ else
+ {
+ ItemPointerSetInvalid(&newInvalid.pointerData);
+ }
+
+ SpinAcquire(SInvalLock);
+ if (!SISetDataEntry(shmInvalBuffer, &newInvalid))
+ {
+ /* buffer full */
+ /* release a message, mark process cache states to be invalid */
+ SISetProcStateInvalid(shmInvalBuffer);
+
+ if (!SIDelDataEntry(shmInvalBuffer))
+ {
+ /* inconsistent buffer state -- shd never happen */
+ SpinRelease(SInvalLock);
+ elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
+ }
+
+ /* write again */
+ SISetDataEntry(shmInvalBuffer, &newInvalid);
+ }
+ SpinRelease(SInvalLock);
}
/*
* InvalidateSharedInvalid --
- * Processes all entries in a shared cache invalidation state.
+ * Processes all entries in a shared cache invalidation state.
*/
/****************************************************************************/
-/* InvalidateSharedInvalid(invalFunction, resetFunction) */
-/* */
-/* invalidate a message in the buffer (read and clean up) */
-/* should be called by a backend */
+/* InvalidateSharedInvalid(invalFunction, resetFunction) */
+/* */
+/* invalidate a message in the buffer (read and clean up) */
+/* should be called by a backend */
/****************************************************************************/
void
-InvalidateSharedInvalid(void (*invalFunction)(),
- void (*resetFunction)())
+ InvalidateSharedInvalid(void (*invalFunction) (),
+ void (*resetFunction) ())
{
- SpinAcquire(SInvalLock);
- SIReadEntryData(shmInvalBuffer, MyBackendId,
- invalFunction, resetFunction);
-
- SIDelExpiredDataEntries(shmInvalBuffer);
- SpinRelease(SInvalLock);
+ SpinAcquire(SInvalLock);
+ SIReadEntryData(shmInvalBuffer, MyBackendId,
+ invalFunction, resetFunction);
+
+ SIDelExpiredDataEntries(shmInvalBuffer);
+ SpinRelease(SInvalLock);
}
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 9400e872617..43c4d7c0ac2 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* sinvaladt.c--
- * POSTGRES shared cache invalidation segment definitions.
+ * POSTGRES shared cache invalidation segment definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.5 1997/08/12 22:54:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.6 1997/09/07 04:48:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,420 +22,445 @@
#include "utils/palloc.h"
/* ----------------
- * global variable notes
+ * global variable notes
*
- * SharedInvalidationSemaphore
+ * SharedInvalidationSemaphore
*
- * shmInvalBuffer
- * the shared buffer segment, set by SISegmentAttach()
+ * shmInvalBuffer
+ * the shared buffer segment, set by SISegmentAttach()
*
- * MyBackendId
- * might be removed later, used only for
- * debugging in debug routines (end of file)
+ * MyBackendId
+ * might be removed later, used only for
+ * debugging in debug routines (end of file)
*
- * SIDbId
- * identification of buffer (disappears)
+ * SIDbId
+ * identification of buffer (disappears)
*
- * SIRelId \
- * SIDummyOid \ identification of buffer
- * SIXidData /
- * SIXid /
+ * SIRelId \
+ * SIDummyOid \ identification of buffer
+ * SIXidData /
+ * SIXid /
*
- * XXX This file really needs to be cleaned up. We switched to using
- * spinlocks to protect critical sections (as opposed to using fake
- * relations and going through the lock manager) and some of the old
- * cruft was 'ifdef'ed out, while other parts (now unused) are still
- * compiled into the system. -mer 5/24/92
+ * XXX This file really needs to be cleaned up. We switched to using
+ * spinlocks to protect critical sections (as opposed to using fake
+ * relations and going through the lock manager) and some of the old
+ * cruft was 'ifdef'ed out, while other parts (now unused) are still
+ * compiled into the system. -mer 5/24/92
* ----------------
*/
#ifdef HAS_TEST_AND_SET
-int SharedInvalidationLockId;
+int SharedInvalidationLockId;
+
#else
IpcSemaphoreId SharedInvalidationSemaphore;
+
#endif
-SISeg *shmInvalBuffer;
+SISeg *shmInvalBuffer;
extern BackendId MyBackendId;
-static void CleanupInvalidationState(int status, SISeg *segInOutP);
-static BackendId SIAssignBackendId(SISeg *segInOutP, BackendTag backendTag);
-static int SIGetNumEntries(SISeg *segP);
+static void CleanupInvalidationState(int status, SISeg * segInOutP);
+static BackendId SIAssignBackendId(SISeg * segInOutP, BackendTag backendTag);
+static int SIGetNumEntries(SISeg * segP);
/************************************************************************/
/* SISetActiveProcess(segP, backendId) set the backend status active */
-/* should be called only by the postmaster when creating a backend */
+/* should be called only by the postmaster when creating a backend */
/************************************************************************/
/* XXX I suspect that the segP parameter is extraneous. -hirohama */
static void
-SISetActiveProcess(SISeg *segInOutP, BackendId backendId)
+SISetActiveProcess(SISeg * segInOutP, BackendId backendId)
{
- /* mark all messages as read */
-
- /* Assert(segP->procState[backendId - 1].tag == MyBackendTag); */
-
- segInOutP->procState[backendId - 1].resetState = false;
- segInOutP->procState[backendId - 1].limit = SIGetNumEntries(segInOutP);
+ /* mark all messages as read */
+
+ /* Assert(segP->procState[backendId - 1].tag == MyBackendTag); */
+
+ segInOutP->procState[backendId - 1].resetState = false;
+ segInOutP->procState[backendId - 1].limit = SIGetNumEntries(segInOutP);
}
/****************************************************************************/
-/* SIBackendInit() initializes a backend to operate on the buffer */
+/* SIBackendInit() initializes a backend to operate on the buffer */
/****************************************************************************/
int
-SIBackendInit(SISeg *segInOutP)
-{
- LRelId LtCreateRelId();
- TransactionId LMITransactionIdCopy();
-
- Assert(MyBackendTag > 0);
-
- MyBackendId = SIAssignBackendId(segInOutP, MyBackendTag);
- if (MyBackendId == InvalidBackendTag)
- return 0;
-
+SIBackendInit(SISeg * segInOutP)
+{
+ LRelId LtCreateRelId();
+ TransactionId LMITransactionIdCopy();
+
+ Assert(MyBackendTag > 0);
+
+ MyBackendId = SIAssignBackendId(segInOutP, MyBackendTag);
+ if (MyBackendId == InvalidBackendTag)
+ return 0;
+
#ifdef INVALIDDEBUG
- elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",
- MyBackendTag, MyBackendId);
-#endif /* INVALIDDEBUG */
-
- SISetActiveProcess(segInOutP, MyBackendId);
- on_exitpg(CleanupInvalidationState, (caddr_t)segInOutP);
- return 1;
+ elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",
+ MyBackendTag, MyBackendId);
+#endif /* INVALIDDEBUG */
+
+ SISetActiveProcess(segInOutP, MyBackendId);
+ on_exitpg(CleanupInvalidationState, (caddr_t) segInOutP);
+ return 1;
}
/* ----------------
- * SIAssignBackendId
+ * SIAssignBackendId
* ----------------
*/
-static BackendId
-SIAssignBackendId(SISeg *segInOutP, BackendTag backendTag)
-{
- Index index;
- ProcState *stateP;
-
- stateP = NULL;
-
- for (index = 0; index < MaxBackendId; index += 1) {
- if (segInOutP->procState[index].tag == InvalidBackendTag ||
- segInOutP->procState[index].tag == backendTag)
- {
- stateP = &segInOutP->procState[index];
- break;
- }
-
- if (!PointerIsValid(stateP) ||
- (segInOutP->procState[index].resetState &&
- (!stateP->resetState ||
- stateP->tag < backendTag)) ||
- (!stateP->resetState &&
- (segInOutP->procState[index].limit <
- stateP->limit ||
- stateP->tag < backendTag)))
- {
- stateP = &segInOutP->procState[index];
- }
- }
-
- /* verify that all "procState" entries checked for matching tags */
-
- for (index += 1; index < MaxBackendId; index += 1) {
- if (segInOutP->procState[index].tag == backendTag) {
- elog (FATAL, "SIAssignBackendId: tag %d found twice",
- backendTag);
+static BackendId
+SIAssignBackendId(SISeg * segInOutP, BackendTag backendTag)
+{
+ Index index;
+ ProcState *stateP;
+
+ stateP = NULL;
+
+ for (index = 0; index < MaxBackendId; index += 1)
+ {
+ if (segInOutP->procState[index].tag == InvalidBackendTag ||
+ segInOutP->procState[index].tag == backendTag)
+ {
+ stateP = &segInOutP->procState[index];
+ break;
+ }
+
+ if (!PointerIsValid(stateP) ||
+ (segInOutP->procState[index].resetState &&
+ (!stateP->resetState ||
+ stateP->tag < backendTag)) ||
+ (!stateP->resetState &&
+ (segInOutP->procState[index].limit <
+ stateP->limit ||
+ stateP->tag < backendTag)))
+ {
+ stateP = &segInOutP->procState[index];
+ }
+ }
+
+ /* verify that all "procState" entries checked for matching tags */
+
+ for (index += 1; index < MaxBackendId; index += 1)
+ {
+ if (segInOutP->procState[index].tag == backendTag)
+ {
+ elog(FATAL, "SIAssignBackendId: tag %d found twice",
+ backendTag);
+ }
}
- }
-
- if (stateP->tag != InvalidBackendTag) {
- if (stateP->tag == backendTag) {
- elog(NOTICE, "SIAssignBackendId: reusing tag %d",
- backendTag);
- } else {
- elog(NOTICE,
- "SIAssignBackendId: discarding tag %d",
- stateP->tag);
- return InvalidBackendTag;
+
+ if (stateP->tag != InvalidBackendTag)
+ {
+ if (stateP->tag == backendTag)
+ {
+ elog(NOTICE, "SIAssignBackendId: reusing tag %d",
+ backendTag);
+ }
+ else
+ {
+ elog(NOTICE,
+ "SIAssignBackendId: discarding tag %d",
+ stateP->tag);
+ return InvalidBackendTag;
+ }
}
- }
-
- stateP->tag = backendTag;
-
- return (1 + stateP - &segInOutP->procState[0]);
+
+ stateP->tag = backendTag;
+
+ return (1 + stateP - &segInOutP->procState[0]);
}
/************************************************************************/
-/* The following function should be called only by the postmaster !! */
+/* The following function should be called only by the postmaster !! */
/************************************************************************/
/************************************************************************/
-/* SISetDeadProcess(segP, backendId) set the backend status DEAD */
-/* should be called only by the postmaster when a backend died */
+/* SISetDeadProcess(segP, backendId) set the backend status DEAD */
+/* should be called only by the postmaster when a backend died */
/************************************************************************/
static void
-SISetDeadProcess(SISeg *segP, int backendId)
+SISetDeadProcess(SISeg * segP, int backendId)
{
- /* XXX call me.... */
-
- segP->procState[backendId - 1].resetState = false;
- segP->procState[backendId - 1].limit = -1;
- segP->procState[backendId - 1].tag = InvalidBackendTag;
+ /* XXX call me.... */
+
+ segP->procState[backendId - 1].resetState = false;
+ segP->procState[backendId - 1].limit = -1;
+ segP->procState[backendId - 1].tag = InvalidBackendTag;
}
/*
* CleanupInvalidationState --
* Note:
- * This is a temporary hack. ExitBackend should call this instead
- * of exit (via on_exitpg).
+ * This is a temporary hack. ExitBackend should call this instead
+ * of exit (via on_exitpg).
*/
static void
-CleanupInvalidationState(int status, /* XXX */
- SISeg *segInOutP) /* XXX style */
+CleanupInvalidationState(int status, /* XXX */
+ SISeg * segInOutP) /* XXX style */
{
- Assert(PointerIsValid(segInOutP));
-
- SISetDeadProcess(segInOutP, MyBackendId);
+ Assert(PointerIsValid(segInOutP));
+
+ SISetDeadProcess(segInOutP, MyBackendId);
}
/************************************************************************/
-/* SIComputeSize() - retuns the size of a buffer segment */
+/* SIComputeSize() - retuns the size of a buffer segment */
/************************************************************************/
static SISegOffsets *
SIComputeSize(int *segSize)
{
- int A, B, a, b, totalSize;
- SISegOffsets *oP;
-
- A = 0;
- a = SizeSISeg; /* offset to first data entry */
- b = SizeOfOneSISegEntry * MAXNUMMESSAGES;
- B = A + a + b;
- totalSize = B - A;
- *segSize = totalSize;
-
- oP = (SISegOffsets *) palloc(sizeof(SISegOffsets));
- oP->startSegment = A;
- oP->offsetToFirstEntry = a; /* relatiove to A */
- oP->offsetToEndOfSegemnt = totalSize; /* relative to A */
- return(oP);
+ int A,
+ B,
+ a,
+ b,
+ totalSize;
+ SISegOffsets *oP;
+
+ A = 0;
+ a = SizeSISeg; /* offset to first data entry */
+ b = SizeOfOneSISegEntry * MAXNUMMESSAGES;
+ B = A + a + b;
+ totalSize = B - A;
+ *segSize = totalSize;
+
+ oP = (SISegOffsets *) palloc(sizeof(SISegOffsets));
+ oP->startSegment = A;
+ oP->offsetToFirstEntry = a; /* relatiove to A */
+ oP->offsetToEndOfSegemnt = totalSize; /* relative to A */
+ return (oP);
}
/************************************************************************/
-/* SISetStartEntrySection(segP, offset) - sets the offset */
+/* SISetStartEntrySection(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartEntrySection(SISeg *segP, Offset offset)
+SISetStartEntrySection(SISeg * segP, Offset offset)
{
- segP->startEntrySection = offset;
+ segP->startEntrySection = offset;
}
/************************************************************************/
-/* SIGetStartEntrySection(segP) - returnss the offset */
+/* SIGetStartEntrySection(segP) - returnss the offset */
/************************************************************************/
-static Offset
-SIGetStartEntrySection(SISeg *segP)
+static Offset
+SIGetStartEntrySection(SISeg * segP)
{
- return(segP->startEntrySection);
+ return (segP->startEntrySection);
}
/************************************************************************/
-/* SISetEndEntrySection(segP, offset) - sets the offset */
+/* SISetEndEntrySection(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetEndEntrySection(SISeg *segP, Offset offset)
+SISetEndEntrySection(SISeg * segP, Offset offset)
{
- segP->endEntrySection = offset;
+ segP->endEntrySection = offset;
}
/************************************************************************/
-/* SISetEndEntryChain(segP, offset) - sets the offset */
+/* SISetEndEntryChain(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetEndEntryChain(SISeg *segP, Offset offset)
+SISetEndEntryChain(SISeg * segP, Offset offset)
{
- segP->endEntryChain = offset;
+ segP->endEntryChain = offset;
}
/************************************************************************/
-/* SIGetEndEntryChain(segP) - returnss the offset */
+/* SIGetEndEntryChain(segP) - returnss the offset */
/************************************************************************/
-static Offset
-SIGetEndEntryChain(SISeg *segP)
+static Offset
+SIGetEndEntryChain(SISeg * segP)
{
- return(segP->endEntryChain);
+ return (segP->endEntryChain);
}
/************************************************************************/
-/* SISetStartEntryChain(segP, offset) - sets the offset */
+/* SISetStartEntryChain(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartEntryChain(SISeg *segP, Offset offset)
+SISetStartEntryChain(SISeg * segP, Offset offset)
{
- segP->startEntryChain = offset;
+ segP->startEntryChain = offset;
}
/************************************************************************/
-/* SIGetStartEntryChain(segP) - returns the offset */
+/* SIGetStartEntryChain(segP) - returns the offset */
/************************************************************************/
-static Offset
-SIGetStartEntryChain(SISeg *segP)
+static Offset
+SIGetStartEntryChain(SISeg * segP)
{
- return(segP->startEntryChain);
+ return (segP->startEntryChain);
}
/************************************************************************/
-/* SISetNumEntries(segP, num) sets the current nuber of entries */
+/* SISetNumEntries(segP, num) sets the current nuber of entries */
/************************************************************************/
-static bool
-SISetNumEntries(SISeg *segP, int num)
+static bool
+SISetNumEntries(SISeg * segP, int num)
{
- if ( num <= MAXNUMMESSAGES) {
- segP->numEntries = num;
- return(true);
- } else {
- return(false); /* table full */
- }
+ if (num <= MAXNUMMESSAGES)
+ {
+ segP->numEntries = num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* table full */
+ }
}
/************************************************************************/
-/* SIGetNumEntries(segP) - returns the current nuber of entries */
+/* SIGetNumEntries(segP) - returns the current nuber of entries */
/************************************************************************/
static int
-SIGetNumEntries(SISeg *segP)
+SIGetNumEntries(SISeg * segP)
{
- return(segP->numEntries);
+ return (segP->numEntries);
}
/************************************************************************/
-/* SISetMaxNumEntries(segP, num) sets the maximal number of entries */
+/* SISetMaxNumEntries(segP, num) sets the maximal number of entries */
/************************************************************************/
-static bool
-SISetMaxNumEntries(SISeg *segP, int num)
+static bool
+SISetMaxNumEntries(SISeg * segP, int num)
{
- if ( num <= MAXNUMMESSAGES) {
- segP->maxNumEntries = num;
- return(true);
- } else {
- return(false); /* wrong number */
- }
+ if (num <= MAXNUMMESSAGES)
+ {
+ segP->maxNumEntries = num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* wrong number */
+ }
}
/************************************************************************/
-/* SIGetProcStateLimit(segP, i) returns the limit of read messages */
+/* SIGetProcStateLimit(segP, i) returns the limit of read messages */
/************************************************************************/
static int
-SIGetProcStateLimit(SISeg *segP, int i)
+SIGetProcStateLimit(SISeg * segP, int i)
{
- return(segP->procState[i].limit);
+ return (segP->procState[i].limit);
}
/************************************************************************/
-/* SIIncNumEntries(segP, num) increments the current nuber of entries */
+/* SIIncNumEntries(segP, num) increments the current nuber of entries */
/************************************************************************/
-static bool
-SIIncNumEntries(SISeg *segP, int num)
+static bool
+SIIncNumEntries(SISeg * segP, int num)
{
- if ((segP->numEntries + num) <= MAXNUMMESSAGES) {
- segP->numEntries = segP->numEntries + num;
- return(true);
- } else {
- return(false); /* table full */
- }
+ if ((segP->numEntries + num) <= MAXNUMMESSAGES)
+ {
+ segP->numEntries = segP->numEntries + num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* table full */
+ }
}
/************************************************************************/
-/* SIDecNumEntries(segP, num) decrements the current nuber of entries */
+/* SIDecNumEntries(segP, num) decrements the current nuber of entries */
/************************************************************************/
-static bool
-SIDecNumEntries(SISeg *segP, int num)
+static bool
+SIDecNumEntries(SISeg * segP, int num)
{
- if ((segP->numEntries - num) >= 0) {
- segP->numEntries = segP->numEntries - num;
- return(true);
- } else {
- return(false); /* not enough entries in table */
- }
+ if ((segP->numEntries - num) >= 0)
+ {
+ segP->numEntries = segP->numEntries - num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* not enough entries in table */
+ }
}
/************************************************************************/
-/* SISetStartFreeSpace(segP, offset) - sets the offset */
+/* SISetStartFreeSpace(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartFreeSpace(SISeg *segP, Offset offset)
+SISetStartFreeSpace(SISeg * segP, Offset offset)
{
- segP->startFreeSpace = offset;
+ segP->startFreeSpace = offset;
}
/************************************************************************/
-/* SIGetStartFreeSpace(segP) - returns the offset */
+/* SIGetStartFreeSpace(segP) - returns the offset */
/************************************************************************/
-static Offset
-SIGetStartFreeSpace(SISeg *segP)
+static Offset
+SIGetStartFreeSpace(SISeg * segP)
{
- return(segP->startFreeSpace);
+ return (segP->startFreeSpace);
}
/************************************************************************/
-/* SIGetFirstDataEntry(segP) returns first data entry */
+/* SIGetFirstDataEntry(segP) returns first data entry */
/************************************************************************/
static SISegEntry *
-SIGetFirstDataEntry(SISeg *segP)
+SIGetFirstDataEntry(SISeg * segP)
{
- SISegEntry *eP;
- Offset startChain;
-
- startChain = SIGetStartEntryChain(segP);
-
- if (startChain == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- startChain );
- return(eP);
+ SISegEntry *eP;
+ Offset startChain;
+
+ startChain = SIGetStartEntryChain(segP);
+
+ if (startChain == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ startChain);
+ return (eP);
}
/************************************************************************/
-/* SIGetLastDataEntry(segP) returns last data entry in the chain */
+/* SIGetLastDataEntry(segP) returns last data entry in the chain */
/************************************************************************/
static SISegEntry *
-SIGetLastDataEntry(SISeg *segP)
+SIGetLastDataEntry(SISeg * segP)
{
- SISegEntry *eP;
- Offset endChain;
-
- endChain = SIGetEndEntryChain(segP);
-
- if (endChain == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- endChain );
- return(eP);
+ SISegEntry *eP;
+ Offset endChain;
+
+ endChain = SIGetEndEntryChain(segP);
+
+ if (endChain == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ endChain);
+ return (eP);
}
/************************************************************************/
-/* SIGetNextDataEntry(segP, offset) returns next data entry */
+/* SIGetNextDataEntry(segP, offset) returns next data entry */
/************************************************************************/
static SISegEntry *
-SIGetNextDataEntry(SISeg *segP, Offset offset)
+SIGetNextDataEntry(SISeg * segP, Offset offset)
{
- SISegEntry *eP;
-
- if (offset == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- offset);
- return(eP);
+ SISegEntry *eP;
+
+ if (offset == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ offset);
+ return (eP);
}
@@ -443,352 +468,396 @@ SIGetNextDataEntry(SISeg *segP, Offset offset)
/* SIGetNthDataEntry(segP, n) returns the n-th data entry in chain */
/************************************************************************/
static SISegEntry *
-SIGetNthDataEntry(SISeg *segP,
- int n) /* must range from 1 to MaxMessages */
+SIGetNthDataEntry(SISeg * segP,
+ int n) /* must range from 1 to MaxMessages */
{
- SISegEntry *eP;
- int i;
-
- if (n <= 0) return(NULL);
-
- eP = SIGetFirstDataEntry(segP);
- for (i = 1; i < n; i++) {
- /* skip one and get the next */
- eP = SIGetNextDataEntry(segP, eP->next);
- }
-
- return(eP);
+ SISegEntry *eP;
+ int i;
+
+ if (n <= 0)
+ return (NULL);
+
+ eP = SIGetFirstDataEntry(segP);
+ for (i = 1; i < n; i++)
+ {
+ /* skip one and get the next */
+ eP = SIGetNextDataEntry(segP, eP->next);
+ }
+
+ return (eP);
}
/************************************************************************/
-/* SIEntryOffset(segP, entryP) returns the offset for an pointer */
+/* SIEntryOffset(segP, entryP) returns the offset for an pointer */
/************************************************************************/
-static Offset
-SIEntryOffset(SISeg *segP, SISegEntry *entryP)
+static Offset
+SIEntryOffset(SISeg * segP, SISegEntry * entryP)
{
- /* relative to B !! */
- return ((Offset) ((Pointer) entryP -
- (Pointer) segP -
- SIGetStartEntrySection(segP) ));
+ /* relative to B !! */
+ return ((Offset) ((Pointer) entryP -
+ (Pointer) segP -
+ SIGetStartEntrySection(segP)));
}
/************************************************************************/
-/* SISetDataEntry(segP, data) - sets a message in the segemnt */
+/* SISetDataEntry(segP, data) - sets a message in the segemnt */
/************************************************************************/
bool
-SISetDataEntry(SISeg *segP, SharedInvalidData *data)
-{
- Offset offsetToNewData;
- SISegEntry *eP, *lastP;
-
- if (!SIIncNumEntries(segP, 1))
- return(false); /* no space */
-
- /* get a free entry */
- offsetToNewData = SIGetStartFreeSpace(segP);
- eP = SIGetNextDataEntry(segP, offsetToNewData); /* it's a free one */
- SISetStartFreeSpace(segP, eP->next);
- /* fill it up */
- eP->entryData = *data;
- eP->isfree = false;
- eP->next = InvalidOffset;
-
- /* handle insertion point at the end of the chain !!*/
- lastP = SIGetLastDataEntry(segP);
- if (lastP == NULL) {
- /* there is no chain, insert the first entry */
- SISetStartEntryChain(segP, SIEntryOffset(segP, eP));
- } else {
- /* there is a last entry in the chain */
- lastP->next = SIEntryOffset(segP, eP);
- }
- SISetEndEntryChain(segP, SIEntryOffset(segP, eP));
- return(true);
-}
-
-
-/************************************************************************/
-/* SIDecProcLimit(segP, num) decrements all process limits */
+SISetDataEntry(SISeg * segP, SharedInvalidData * data)
+{
+ Offset offsetToNewData;
+ SISegEntry *eP,
+ *lastP;
+
+ if (!SIIncNumEntries(segP, 1))
+ return (false); /* no space */
+
+ /* get a free entry */
+ offsetToNewData = SIGetStartFreeSpace(segP);
+ eP = SIGetNextDataEntry(segP, offsetToNewData); /* it's a free one */
+ SISetStartFreeSpace(segP, eP->next);
+ /* fill it up */
+ eP->entryData = *data;
+ eP->isfree = false;
+ eP->next = InvalidOffset;
+
+ /* handle insertion point at the end of the chain !! */
+ lastP = SIGetLastDataEntry(segP);
+ if (lastP == NULL)
+ {
+ /* there is no chain, insert the first entry */
+ SISetStartEntryChain(segP, SIEntryOffset(segP, eP));
+ }
+ else
+ {
+ /* there is a last entry in the chain */
+ lastP->next = SIEntryOffset(segP, eP);
+ }
+ SISetEndEntryChain(segP, SIEntryOffset(segP, eP));
+ return (true);
+}
+
+
+/************************************************************************/
+/* SIDecProcLimit(segP, num) decrements all process limits */
/************************************************************************/
static void
-SIDecProcLimit(SISeg *segP, int num)
-{
- int i;
- for (i=0; i < MaxBackendId; i++) {
- /* decrement only, if there is a limit > 0 */
- if (segP->procState[i].limit > 0) {
- segP->procState[i].limit = segP->procState[i].limit - num;
- if (segP->procState[i].limit < 0) {
- /* limit was not high enough, reset to zero */
- /* negative means it's a dead backend */
- segP->procState[i].limit = 0;
- }
- }
- }
+SIDecProcLimit(SISeg * segP, int num)
+{
+ int i;
+
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ /* decrement only, if there is a limit > 0 */
+ if (segP->procState[i].limit > 0)
+ {
+ segP->procState[i].limit = segP->procState[i].limit - num;
+ if (segP->procState[i].limit < 0)
+ {
+ /* limit was not high enough, reset to zero */
+ /* negative means it's a dead backend */
+ segP->procState[i].limit = 0;
+ }
+ }
+ }
}
/************************************************************************/
-/* SIDelDataEntry(segP) - free the FIRST entry */
+/* SIDelDataEntry(segP) - free the FIRST entry */
/************************************************************************/
bool
-SIDelDataEntry(SISeg *segP)
+SIDelDataEntry(SISeg * segP)
{
- SISegEntry *e1P;
-
- if (!SIDecNumEntries(segP, 1)) {
- /* no entries in buffer */
- return(false);
- }
-
- e1P = SIGetFirstDataEntry(segP);
- SISetStartEntryChain(segP, e1P->next);
- if (SIGetStartEntryChain(segP) == InvalidOffset) {
- /* it was the last entry */
- SISetEndEntryChain(segP, InvalidOffset);
- }
- /* free the entry */
- e1P->isfree = true;
- e1P->next = SIGetStartFreeSpace(segP);
- SISetStartFreeSpace(segP, SIEntryOffset(segP, e1P));
- SIDecProcLimit(segP, 1);
- return(true);
+ SISegEntry *e1P;
+
+ if (!SIDecNumEntries(segP, 1))
+ {
+ /* no entries in buffer */
+ return (false);
+ }
+
+ e1P = SIGetFirstDataEntry(segP);
+ SISetStartEntryChain(segP, e1P->next);
+ if (SIGetStartEntryChain(segP) == InvalidOffset)
+ {
+ /* it was the last entry */
+ SISetEndEntryChain(segP, InvalidOffset);
+ }
+ /* free the entry */
+ e1P->isfree = true;
+ e1P->next = SIGetStartFreeSpace(segP);
+ SISetStartFreeSpace(segP, SIEntryOffset(segP, e1P));
+ SIDecProcLimit(segP, 1);
+ return (true);
}
/************************************************************************/
-/* SISetProcStateInvalid(segP) checks and marks a backends state as */
-/* invalid */
+/* SISetProcStateInvalid(segP) checks and marks a backends state as */
+/* invalid */
/************************************************************************/
void
-SISetProcStateInvalid(SISeg *segP)
-{
- int i;
-
- for (i=0; i < MaxBackendId; i++) {
- if (segP->procState[i].limit == 0) {
- /* backend i didn't read any message */
- segP->procState[i].resetState = true;
- /*XXX signal backend that it has to reset its internal cache ? */
- }
- }
+SISetProcStateInvalid(SISeg * segP)
+{
+ int i;
+
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ if (segP->procState[i].limit == 0)
+ {
+ /* backend i didn't read any message */
+ segP->procState[i].resetState = true;
+
+ /*
+ * XXX signal backend that it has to reset its internal cache
+ * ?
+ */
+ }
+ }
}
/************************************************************************/
-/* SIReadEntryData(segP, backendId, function) */
-/* - marks messages to be read by id */
-/* and executes function */
+/* SIReadEntryData(segP, backendId, function) */
+/* - marks messages to be read by id */
+/* and executes function */
/************************************************************************/
void
-SIReadEntryData(SISeg *segP,
- int backendId,
- void (*invalFunction)(),
- void (*resetFunction)())
-{
- int i = 0;
- SISegEntry *data;
-
- Assert(segP->procState[backendId - 1].tag == MyBackendTag);
-
- if (!segP->procState[backendId - 1].resetState) {
- /* invalidate data, but only those, you have not seen yet !!*/
- /* therefore skip read messages */
- data = SIGetNthDataEntry(segP,
- SIGetProcStateLimit(segP, backendId - 1) + 1);
- while (data != NULL) {
- i++;
- segP->procState[backendId - 1].limit++; /* one more message read */
- invalFunction(data->entryData.cacheId,
- data->entryData.hashIndex,
- &data->entryData.pointerData);
- data = SIGetNextDataEntry(segP, data->next);
- }
- /* SIDelExpiredDataEntries(segP); */
- } else {
- /*backend must not read messages, its own state has to be reset */
- elog(NOTICE, "SIMarkEntryData: cache state reset");
- resetFunction(); /* XXXX call it here, parameters? */
-
- /* new valid state--mark all messages "read" */
- segP->procState[backendId - 1].resetState = false;
- segP->procState[backendId - 1].limit = SIGetNumEntries(segP);
- }
- /* check whether we can remove dead messages */
- if (i > MAXNUMMESSAGES) {
- elog(FATAL, "SIReadEntryData: Invalid segment state");
- }
+SIReadEntryData(SISeg * segP,
+ int backendId,
+ void (*invalFunction) (),
+ void (*resetFunction) ())
+{
+ int i = 0;
+ SISegEntry *data;
+
+ Assert(segP->procState[backendId - 1].tag == MyBackendTag);
+
+ if (!segP->procState[backendId - 1].resetState)
+ {
+ /* invalidate data, but only those, you have not seen yet !! */
+ /* therefore skip read messages */
+ data = SIGetNthDataEntry(segP,
+ SIGetProcStateLimit(segP, backendId - 1) + 1);
+ while (data != NULL)
+ {
+ i++;
+ segP->procState[backendId - 1].limit++; /* one more message read */
+ invalFunction(data->entryData.cacheId,
+ data->entryData.hashIndex,
+ &data->entryData.pointerData);
+ data = SIGetNextDataEntry(segP, data->next);
+ }
+ /* SIDelExpiredDataEntries(segP); */
+ }
+ else
+ {
+ /* backend must not read messages, its own state has to be reset */
+ elog(NOTICE, "SIMarkEntryData: cache state reset");
+ resetFunction(); /* XXXX call it here, parameters? */
+
+ /* new valid state--mark all messages "read" */
+ segP->procState[backendId - 1].resetState = false;
+ segP->procState[backendId - 1].limit = SIGetNumEntries(segP);
+ }
+ /* check whether we can remove dead messages */
+ if (i > MAXNUMMESSAGES)
+ {
+ elog(FATAL, "SIReadEntryData: Invalid segment state");
+ }
}
/************************************************************************/
-/* SIDelExpiredDataEntries (segP) - removes irrelevant messages */
+/* SIDelExpiredDataEntries (segP) - removes irrelevant messages */
/************************************************************************/
void
-SIDelExpiredDataEntries(SISeg *segP)
-{
- int min, i, h;
-
- min = 9999999;
- for (i = 0; i < MaxBackendId; i++) {
- h = SIGetProcStateLimit(segP, i);
- if (h >= 0) { /* backend active */
- if (h < min ) min = h;
- }
- }
- if (min != 9999999) {
- /* we can remove min messages */
- for (i = 1; i <= min; i++) {
- /* this adjusts also the state limits!*/
- if (!SIDelDataEntry(segP)) {
- elog(FATAL, "SIDelExpiredDataEntries: Invalid segment state");
- }
- }
- }
+SIDelExpiredDataEntries(SISeg * segP)
+{
+ int min,
+ i,
+ h;
+
+ min = 9999999;
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ h = SIGetProcStateLimit(segP, i);
+ if (h >= 0)
+ { /* backend active */
+ if (h < min)
+ min = h;
+ }
+ }
+ if (min != 9999999)
+ {
+ /* we can remove min messages */
+ for (i = 1; i <= min; i++)
+ {
+ /* this adjusts also the state limits! */
+ if (!SIDelDataEntry(segP))
+ {
+ elog(FATAL, "SIDelExpiredDataEntries: Invalid segment state");
+ }
+ }
+ }
}
/************************************************************************/
-/* SISegInit(segP) - initializes the segment */
+/* SISegInit(segP) - initializes the segment */
/************************************************************************/
static void
-SISegInit(SISeg *segP)
-{
- SISegOffsets *oP;
- int segSize, i;
- SISegEntry *eP;
-
- oP = SIComputeSize(&segSize);
- /* set sempahore ids in the segment */
- /* XXX */
- SISetStartEntrySection(segP, oP->offsetToFirstEntry);
- SISetEndEntrySection(segP, oP->offsetToEndOfSegemnt);
- SISetStartFreeSpace(segP, 0);
- SISetStartEntryChain(segP, InvalidOffset);
- SISetEndEntryChain(segP, InvalidOffset);
- SISetNumEntries(segP, 0);
- SISetMaxNumEntries(segP, MAXNUMMESSAGES);
- for (i = 0; i < MaxBackendId; i++) {
- segP->procState[i].limit = -1; /* no backend active !!*/
- segP->procState[i].resetState = false;
- segP->procState[i].tag = InvalidBackendTag;
- }
- /* construct a chain of free entries */
- for (i = 1; i < MAXNUMMESSAGES; i++) {
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- (i - 1) * sizeof(SISegEntry));
- eP->isfree = true;
- eP->next = i * sizeof(SISegEntry); /* relative to B */
- }
- /* handle the last free entry separate */
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- (MAXNUMMESSAGES - 1) * sizeof(SISegEntry));
- eP->isfree = true;
- eP->next = InvalidOffset; /* it's the end of the chain !! */
- /*
- * Be tidy
- */
- pfree(oP);
-
-}
-
-
-
-/************************************************************************/
-/* SISegmentKill(key) - kill any segment */
+SISegInit(SISeg * segP)
+{
+ SISegOffsets *oP;
+ int segSize,
+ i;
+ SISegEntry *eP;
+
+ oP = SIComputeSize(&segSize);
+ /* set sempahore ids in the segment */
+ /* XXX */
+ SISetStartEntrySection(segP, oP->offsetToFirstEntry);
+ SISetEndEntrySection(segP, oP->offsetToEndOfSegemnt);
+ SISetStartFreeSpace(segP, 0);
+ SISetStartEntryChain(segP, InvalidOffset);
+ SISetEndEntryChain(segP, InvalidOffset);
+ SISetNumEntries(segP, 0);
+ SISetMaxNumEntries(segP, MAXNUMMESSAGES);
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ segP->procState[i].limit = -1; /* no backend active !! */
+ segP->procState[i].resetState = false;
+ segP->procState[i].tag = InvalidBackendTag;
+ }
+ /* construct a chain of free entries */
+ for (i = 1; i < MAXNUMMESSAGES; i++)
+ {
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ (i - 1) * sizeof(SISegEntry));
+ eP->isfree = true;
+ eP->next = i * sizeof(SISegEntry); /* relative to B */
+ }
+ /* handle the last free entry separate */
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ (MAXNUMMESSAGES - 1) * sizeof(SISegEntry));
+ eP->isfree = true;
+ eP->next = InvalidOffset; /* it's the end of the chain !! */
+
+ /*
+ * Be tidy
+ */
+ pfree(oP);
+
+}
+
+
+
+/************************************************************************/
+/* SISegmentKill(key) - kill any segment */
/************************************************************************/
static void
-SISegmentKill(int key) /* the corresponding key for the segment */
-{
- IpcMemoryKill(key);
-}
+SISegmentKill(int key) /* the corresponding key for the segment */
+{
+ IpcMemoryKill(key);
+}
/************************************************************************/
-/* SISegmentGet(key, size) - get a shared segment of size <size> */
-/* returns a segment id */
+/* SISegmentGet(key, size) - get a shared segment of size <size> */
+/* returns a segment id */
/************************************************************************/
-static IpcMemoryId
-SISegmentGet(int key, /* the corresponding key for the segment */
- int size, /* size of segment in bytes */
- bool create)
+static IpcMemoryId
+SISegmentGet(int key, /* the corresponding key for the segment */
+ int size, /* size of segment in bytes */
+ bool create)
{
- IpcMemoryId shmid;
-
- if (create) {
- shmid = IpcMemoryCreate(key, size, IPCProtection);
- } else {
- shmid = IpcMemoryIdGet(key, size);
- }
- return(shmid);
+ IpcMemoryId shmid;
+
+ if (create)
+ {
+ shmid = IpcMemoryCreate(key, size, IPCProtection);
+ }
+ else
+ {
+ shmid = IpcMemoryIdGet(key, size);
+ }
+ return (shmid);
}
/************************************************************************/
-/* SISegmentAttach(shmid) - attach a shared segment with id shmid */
+/* SISegmentAttach(shmid) - attach a shared segment with id shmid */
/************************************************************************/
static void
SISegmentAttach(IpcMemoryId shmid)
{
- shmInvalBuffer = (struct SISeg *) IpcMemoryAttach(shmid);
- if (shmInvalBuffer == IpcMemAttachFailed) {
- /* XXX use validity function */
- elog(NOTICE, "SISegmentAttach: Could not attach segment");
- elog(FATAL, "SISegmentAttach: %m");
- }
+ shmInvalBuffer = (struct SISeg *) IpcMemoryAttach(shmid);
+ if (shmInvalBuffer == IpcMemAttachFailed)
+ {
+ /* XXX use validity function */
+ elog(NOTICE, "SISegmentAttach: Could not attach segment");
+ elog(FATAL, "SISegmentAttach: %m");
+ }
}
/************************************************************************/
-/* SISegmentInit(killExistingSegment, key) initialize segment */
+/* SISegmentInit(killExistingSegment, key) initialize segment */
/************************************************************************/
int
SISegmentInit(bool killExistingSegment, IPCKey key)
-{
- SISegOffsets *oP;
- int segSize;
- IpcMemoryId shmId;
- bool create;
-
- if (killExistingSegment) {
- /* Kill existing segment */
- /* set semaphore */
- SISegmentKill(key);
-
- /* Get a shared segment */
-
- oP = SIComputeSize(&segSize);
- /*
- * Be tidy
- */
- pfree(oP);
-
- create = true;
- shmId = SISegmentGet(key,segSize, create);
- if (shmId < 0) {
- perror("SISegmentGet: failed");
- return(-1); /* an error */
- }
-
- /* Attach the shared cache invalidation segment */
- /* sets the global variable shmInvalBuffer */
- SISegmentAttach(shmId);
-
- /* Init shared memory table */
- SISegInit(shmInvalBuffer);
- } else {
- /* use an existing segment */
- create = false;
- shmId = SISegmentGet(key, 0, create);
- if (shmId < 0) {
- perror("SISegmentGet: getting an existent segment failed");
- return(-1); /* an error */
- }
- /* Attach the shared cache invalidation segment */
- SISegmentAttach(shmId);
- }
- return(1);
-}
+{
+ SISegOffsets *oP;
+ int segSize;
+ IpcMemoryId shmId;
+ bool create;
+
+ if (killExistingSegment)
+ {
+ /* Kill existing segment */
+ /* set semaphore */
+ SISegmentKill(key);
+
+ /* Get a shared segment */
+
+ oP = SIComputeSize(&segSize);
+
+ /*
+ * Be tidy
+ */
+ pfree(oP);
+ create = true;
+ shmId = SISegmentGet(key, segSize, create);
+ if (shmId < 0)
+ {
+ perror("SISegmentGet: failed");
+ return (-1); /* an error */
+ }
+
+ /* Attach the shared cache invalidation segment */
+ /* sets the global variable shmInvalBuffer */
+ SISegmentAttach(shmId);
+
+ /* Init shared memory table */
+ SISegInit(shmInvalBuffer);
+ }
+ else
+ {
+ /* use an existing segment */
+ create = false;
+ shmId = SISegmentGet(key, 0, create);
+ if (shmId < 0)
+ {
+ perror("SISegmentGet: getting an existent segment failed");
+ return (-1); /* an error */
+ }
+ /* Attach the shared cache invalidation segment */
+ SISegmentAttach(shmId);
+ }
+ return (1);
+}
diff --git a/src/backend/storage/ipc/spin.c b/src/backend/storage/ipc/spin.c
index b50d5d9500f..e93d5894a58 100644
--- a/src/backend/storage/ipc/spin.c
+++ b/src/backend/storage/ipc/spin.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* spin.c--
- * routines for managing spin locks
+ * routines for managing spin locks
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.6 1997/08/21 13:43:46 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.7 1997/09/07 04:48:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,8 +21,8 @@
* term semaphores separately anyway.
*
* NOTE: These routines are not supposed to be widely used in Postgres.
- * They are preserved solely for the purpose of porting Mark Sullivan's
- * buffer manager to Postgres.
+ * They are preserved solely for the purpose of porting Mark Sullivan's
+ * buffer manager to Postgres.
*/
#include <errno.h>
#include "postgres.h"
@@ -43,61 +43,62 @@ IpcSemaphoreId SpinLockId;
bool
CreateSpinlocks(IPCKey key)
-{
- /* the spin lock shared memory must have been created by now */
- return(TRUE);
+{
+ /* the spin lock shared memory must have been created by now */
+ return (TRUE);
}
bool
InitSpinLocks(int init, IPCKey key)
{
- extern SPINLOCK ShmemLock;
- extern SPINLOCK BindingLock;
- extern SPINLOCK BufMgrLock;
- extern SPINLOCK LockMgrLock;
- extern SPINLOCK ProcStructLock;
- extern SPINLOCK SInvalLock;
- extern SPINLOCK OidGenLockId;
-
+ extern SPINLOCK ShmemLock;
+ extern SPINLOCK BindingLock;
+ extern SPINLOCK BufMgrLock;
+ extern SPINLOCK LockMgrLock;
+ extern SPINLOCK ProcStructLock;
+ extern SPINLOCK SInvalLock;
+ extern SPINLOCK OidGenLockId;
+
#ifdef MAIN_MEMORY
- extern SPINLOCK MMCacheLock;
-#endif /* SONY_JUKEBOX */
-
- /* These six spinlocks have fixed location is shmem */
- ShmemLock = (SPINLOCK) SHMEMLOCKID;
- BindingLock = (SPINLOCK) BINDINGLOCKID;
- BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
- LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
- ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
- SInvalLock = (SPINLOCK) SINVALLOCKID;
- OidGenLockId = (SPINLOCK) OIDGENLOCKID;
-
+ extern SPINLOCK MMCacheLock;
+
+#endif /* SONY_JUKEBOX */
+
+ /* These six spinlocks have fixed location is shmem */
+ ShmemLock = (SPINLOCK) SHMEMLOCKID;
+ BindingLock = (SPINLOCK) BINDINGLOCKID;
+ BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
+ LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
+ ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
+ SInvalLock = (SPINLOCK) SINVALLOCKID;
+ OidGenLockId = (SPINLOCK) OIDGENLOCKID;
+
#ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
-#endif /* MAIN_MEMORY */
-
- return(TRUE);
+ MMCacheLock = (SPINLOCK) MMCACHELOCKID;
+#endif /* MAIN_MEMORY */
+
+ return (TRUE);
}
void
SpinAcquire(SPINLOCK lock)
{
- ExclusiveLock(lock);
- PROC_INCR_SLOCK(lock);
+ ExclusiveLock(lock);
+ PROC_INCR_SLOCK(lock);
}
void
SpinRelease(SPINLOCK lock)
{
- PROC_DECR_SLOCK(lock);
- ExclusiveUnlock(lock);
+ PROC_DECR_SLOCK(lock);
+ ExclusiveUnlock(lock);
}
-#else /* HAS_TEST_AND_SET */
+#else /* HAS_TEST_AND_SET */
/* Spinlocks are implemented using SysV semaphores */
-static bool AttachSpinLocks(IPCKey key);
-static bool SpinIsLocked(SPINLOCK lock);
+static bool AttachSpinLocks(IPCKey key);
+static bool SpinIsLocked(SPINLOCK lock);
/*
* SpinAcquire -- try to grab a spinlock
@@ -107,86 +108,91 @@ static bool SpinIsLocked(SPINLOCK lock);
void
SpinAcquire(SPINLOCK lock)
{
- IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
- PROC_INCR_SLOCK(lock);
+ IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
+ PROC_INCR_SLOCK(lock);
}
/*
* SpinRelease -- release a spin lock
- *
+ *
* FAILS if the semaphore is corrupted
*/
void
SpinRelease(SPINLOCK lock)
{
- Assert(SpinIsLocked(lock))
+ Assert(SpinIsLocked(lock))
PROC_DECR_SLOCK(lock);
- IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
+ IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
}
-static bool
+static bool
SpinIsLocked(SPINLOCK lock)
{
- int semval;
-
- semval = IpcSemaphoreGetValue(SpinLockId, lock);
- return(semval < IpcSemaphoreDefaultStartValue);
+ int semval;
+
+ semval = IpcSemaphoreGetValue(SpinLockId, lock);
+ return (semval < IpcSemaphoreDefaultStartValue);
}
/*
* CreateSpinlocks -- Create a sysV semaphore array for
- * the spinlocks
+ * the spinlocks
*
*/
bool
CreateSpinlocks(IPCKey key)
{
-
- int status;
- IpcSemaphoreId semid;
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, 1, &status);
- if (status == IpcSemIdExist) {
- IpcSemaphoreKill(key);
- elog(NOTICE,"Destroying old spinlock semaphore");
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, 1, &status);
- }
-
- if (semid >= 0) {
- SpinLockId = semid;
- return(TRUE);
- }
- /* cannot create spinlocks */
- elog(FATAL,"CreateSpinlocks: cannot create spin locks");
- return(FALSE);
+
+ int status;
+ IpcSemaphoreId semid;
+
+ semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
+ IpcSemaphoreDefaultStartValue, 1, &status);
+ if (status == IpcSemIdExist)
+ {
+ IpcSemaphoreKill(key);
+ elog(NOTICE, "Destroying old spinlock semaphore");
+ semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
+ IpcSemaphoreDefaultStartValue, 1, &status);
+ }
+
+ if (semid >= 0)
+ {
+ SpinLockId = semid;
+ return (TRUE);
+ }
+ /* cannot create spinlocks */
+ elog(FATAL, "CreateSpinlocks: cannot create spin locks");
+ return (FALSE);
}
/*
* Attach to existing spinlock set
*/
-static bool
+static bool
AttachSpinLocks(IPCKey key)
{
- IpcSemaphoreId id;
-
- id = semget (key, MAX_SPINS, 0);
- if (id < 0) {
- if (errno == EEXIST) {
- /* key is the name of someone else's semaphore */
- elog (FATAL,"AttachSpinlocks: SPIN_KEY belongs to someone else");
+ IpcSemaphoreId id;
+
+ id = semget(key, MAX_SPINS, 0);
+ if (id < 0)
+ {
+ if (errno == EEXIST)
+ {
+ /* key is the name of someone else's semaphore */
+ elog(FATAL, "AttachSpinlocks: SPIN_KEY belongs to someone else");
+ }
+ /* cannot create spinlocks */
+ elog(FATAL, "AttachSpinlocks: cannot create spin locks");
+ return (FALSE);
}
- /* cannot create spinlocks */
- elog(FATAL,"AttachSpinlocks: cannot create spin locks");
- return(FALSE);
- }
- SpinLockId = id;
- return(TRUE);
+ SpinLockId = id;
+ return (TRUE);
}
/*
* InitSpinLocks -- Spinlock bootstrapping
- *
+ *
* We need several spinlocks for bootstrapping:
* BindingLock (for the shmem binding table) and
* ShmemLock (for the shmem allocator), BufMgrLock (for buffer
@@ -199,41 +205,47 @@ AttachSpinLocks(IPCKey key)
bool
InitSpinLocks(int init, IPCKey key)
{
- extern SPINLOCK ShmemLock;
- extern SPINLOCK BindingLock;
- extern SPINLOCK BufMgrLock;
- extern SPINLOCK LockMgrLock;
- extern SPINLOCK ProcStructLock;
- extern SPINLOCK SInvalLock;
- extern SPINLOCK OidGenLockId;
-
+ extern SPINLOCK ShmemLock;
+ extern SPINLOCK BindingLock;
+ extern SPINLOCK BufMgrLock;
+ extern SPINLOCK LockMgrLock;
+ extern SPINLOCK ProcStructLock;
+ extern SPINLOCK SInvalLock;
+ extern SPINLOCK OidGenLockId;
+
#ifdef MAIN_MEMORY
- extern SPINLOCK MMCacheLock;
-#endif /* MAIN_MEMORY */
-
- if (!init || key != IPC_PRIVATE) {
- /* if bootstrap and key is IPC_PRIVATE, it means that we are running
- * backend by itself. no need to attach spinlocks
- */
- if (! AttachSpinLocks(key)) {
- elog(FATAL,"InitSpinLocks: couldnt attach spin locks");
- return(FALSE);
+ extern SPINLOCK MMCacheLock;
+
+#endif /* MAIN_MEMORY */
+
+ if (!init || key != IPC_PRIVATE)
+ {
+
+ /*
+ * if bootstrap and key is IPC_PRIVATE, it means that we are
+ * running backend by itself. no need to attach spinlocks
+ */
+ if (!AttachSpinLocks(key))
+ {
+ elog(FATAL, "InitSpinLocks: couldnt attach spin locks");
+ return (FALSE);
+ }
}
- }
-
- /* These five (or six) spinlocks have fixed location is shmem */
- ShmemLock = (SPINLOCK) SHMEMLOCKID;
- BindingLock = (SPINLOCK) BINDINGLOCKID;
- BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
- LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
- ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
- SInvalLock = (SPINLOCK) SINVALLOCKID;
- OidGenLockId = (SPINLOCK) OIDGENLOCKID;
-
+
+ /* These five (or six) spinlocks have fixed location is shmem */
+ ShmemLock = (SPINLOCK) SHMEMLOCKID;
+ BindingLock = (SPINLOCK) BINDINGLOCKID;
+ BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
+ LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
+ ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
+ SInvalLock = (SPINLOCK) SINVALLOCKID;
+ OidGenLockId = (SPINLOCK) OIDGENLOCKID;
+
#ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
-#endif /* MAIN_MEMORY */
-
- return(TRUE);
+ MMCacheLock = (SPINLOCK) MMCACHELOCKID;
+#endif /* MAIN_MEMORY */
+
+ return (TRUE);
}
-#endif /* HAS_TEST_AND_SET */
+
+#endif /* HAS_TEST_AND_SET */