1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Massive commit to run PGINDENT on all *.c and *.h files.

This commit is contained in:
Bruce Momjian
1997-09-07 05:04:48 +00:00
parent 8fecd4febf
commit 1ccd423235
687 changed files with 150775 additions and 136888 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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;
#ifdef HAS_TEST_AND_SET
/* ---------------
* 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();
#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");
int size;
/* ----------------
* do process table stuff
* ----------------
*/
InitProcGlobal(key);
on_exitpg(ProcFreeAllSemaphores, 0);
CreateSharedInvalidationState(key);
#ifdef HAS_TEST_AND_SET
/* ---------------
* 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();
#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);
}
/*
* 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);
}

View File

@@ -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");
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 */
#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)
{
slock_t res;
do{
__asm__("ldstub [%1], %0"
: "=&r" (res)
: "r" (lock));
}while(!res != 0);
void
S_LOCK(slock_t * lock)
{
slock_t res;
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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}

View File

@@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 */