home *** CD-ROM | disk | FTP | other *** search
- /*
- * spin.c -- routines for managing spin locks
- *
- * Identification:
- * $Header: /private/postgres/src/storage/ipc/RCS/spin.c,v 1.13 1992/04/13 21:33:36 mer Exp $
- *
- * POSTGRES has two kinds of locks: semaphores (which put the
- * process to sleep) and spinlocks (which are supposed to be
- * short term locks). Currently both are implemented as SysV
- * semaphores, but presumably this can change if we move to
- * a machine with a test-and-set (TAS) instruction. Its probably
- * a good idea to think about (and allocate) short term and long
- * 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.
- */
- #include <errno.h>
- #include "tmp/postgres.h"
- #include "storage/ipc.h"
- #include "storage/ipci.h"
- #include "storage/shmem.h"
- #include "storage/spin.h"
- #include "storage/proc.h"
- #include "utils/log.h"
-
- /* globals used in this file */
- IpcSemaphoreId SpinLockId;
-
- #ifdef HAS_TEST_AND_SET
- /* real spin lock implementations */
-
- CreateSpinlocks(key)
- IPCKey key;
- {
- /* the spin lock shared memory must have been created by now */
- return(TRUE);
- }
-
- AttachSpinLocks(key)
- {
- /* the spin lock shared memory must have been attached by now */
- return(TRUE);
- }
-
- InitSpinLocks(init, key)
- 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;
-
- #ifdef SONY_JUKEBOX
- extern SPINLOCK SJCacheLock;
- extern SPINLOCK JBSpinLock;
- #endif /* SONY_JUKEBOX */
-
- #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;
-
- #ifdef SONY_JUKEBOX
- SJCacheLock = (SPINLOCK) SJCACHELOCKID;
- JBSpinLock = (SPINLOCK) JBSPINLOCKID;
- #endif /* SONY_JUKEBOX */
-
- #ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
- #endif /* MAIN_MEMORY */
-
- return(TRUE);
- }
-
- SpinAcquire(lock)
- SPINLOCK lock;
- {
- ExclusiveLock(lock);
- PROC_INCR_SLOCK(lock);
- }
-
- SpinRelease(lock)
- SPINLOCK lock;
- {
- PROC_DECR_SLOCK(lock);
- ExclusiveUnlock(lock);
- }
-
- SpinIsLocked(lock)
- SPINLOCK lock;
- {
- return(!LockIsFree(lock));
- }
- #else /* HAS_TEST_AND_SET */
- /* Spinlocks are implemented using SysV semaphores */
-
-
- /*
- * SpinAcquire -- try to grab a spinlock
- *
- * FAILS if the semaphore is corrupted.
- */
- SpinAcquire(lock)
- SPINLOCK lock;
- {
- IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
- PROC_INCR_SLOCK(lock);
- }
-
- /*
- * SpinRelease -- release a spin lock
- *
- * FAILS if the semaphore is corrupted
- */
- SpinRelease(lock)
- SPINLOCK lock;
- {
- Assert(SpinIsLocked(lock))
- PROC_DECR_SLOCK(lock);
- IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
- }
-
- int
- SpinIsLocked(lock)
- SPINLOCK lock;
- {
- int semval;
-
- semval = IpcSemaphoreGetValue(SpinLockId, lock);
- return(semval < IpcSemaphoreDefaultStartValue);
- }
-
- /*
- * CreateSpinlocks -- Create a sysV semaphore array for
- * the spinlocks
- *
- */
- CreateSpinlocks(key)
- IPCKey key;
- {
-
- int status;
- IpcSemaphoreId semid;
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, &status);
- if (status == IpcSemIdExist) {
- IpcSemaphoreKill(key);
- elog(NOTICE,"Destroying old spinlock semaphore");
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, &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
- */
- AttachSpinLocks(key)
- IPCKey key;
- {
- IpcSemaphoreId id;
-
- #ifdef linux
- id = semget (key, MAX_SPINS, 0600);
- #else
- id = semget (key, MAX_SPINS, 0);
- #endif
- 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);
- }
- 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
- * pool exclusive access), LockMgrLock (for the lock table), and
- * ProcStructLock (a spin lock for the shared process structure).
- * If there's a Sony WORM drive attached, we also have a spinlock
- * (SJCacheLock) for it. Same story for the main memory storage mgr.
- *
- */
- InitSpinLocks(init, key)
- 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;
-
- #ifdef SONY_JUKEBOX
- extern SPINLOCK SJCacheLock;
- extern SPINLOCK JBSpinLock;
- #endif /* SONY_JUKEBOX */
-
- #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);
- }
- }
-
- /* 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 SONY_JUKEBOX
- SJCacheLock = (SPINLOCK) SJCACHELOCKID;
- JBSpinLock = (SPINLOCK) JBSPINLOCKID;
- #endif /* SONY_JUKEBOX */
-
- #ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
- #endif /* MAIN_MEMORY */
-
- return(TRUE);
- }
- #endif /* HAS_TEST_AND_SET */
-