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:
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user