summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc/shmem.c')
-rw-r--r--src/backend/storage/ipc/shmem.c951
1 files changed, 496 insertions, 455 deletions
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);
+}