diff options
Diffstat (limited to 'src/backend/storage/lmgr')
-rw-r--r-- | src/backend/storage/lmgr/lwlock.c | 8 | ||||
-rw-r--r-- | src/backend/storage/lmgr/proc.c | 296 | ||||
-rw-r--r-- | src/backend/storage/lmgr/spin.c | 143 |
3 files changed, 90 insertions, 357 deletions
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index e85ef7ea11a..8dbf55c0788 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lwlock.c,v 1.9 2002/03/02 21:39:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lwlock.c,v 1.10 2002/05/05 00:03:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -302,7 +302,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode) for (;;) { /* "false" means cannot accept cancel/die interrupt here. */ - IpcSemaphoreLock(proc->sem.semId, proc->sem.semNum, false); + PGSemaphoreLock(&proc->sem, false); if (!proc->lwWaiting) break; extraWaits++; @@ -325,7 +325,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode) * Fix the process wait semaphore's count for any absorbed wakeups. */ while (extraWaits-- > 0) - IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum); + PGSemaphoreUnlock(&proc->sem); } /* @@ -485,7 +485,7 @@ LWLockRelease(LWLockId lockid) head = proc->lwWaitLink; proc->lwWaitLink = NULL; proc->lwWaiting = false; - IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum); + PGSemaphoreUnlock(&proc->sem); } /* diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 99825529558..8ccaff94776 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.118 2002/03/02 21:39:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.119 2002/05/05 00:03:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,12 +37,6 @@ * in the first place was to allow the lock table to grow larger * than available shared memory and that isn't going to work * without a lot of unimplemented support anyway. - * - * 4/7/95 -- instead of allocating a set of 1 semaphore per process, we - * allocate a semaphore from a set of PROC_NSEMS_PER_SET semaphores - * shared among backends (we keep a few sets of semaphores around). - * This is so that we can support more backends. (system-wide semaphore - * sets run out pretty fast.) -ay 4/95 */ #include "postgres.h" @@ -51,18 +45,9 @@ #include <unistd.h> #include <sys/time.h> -#include "storage/ipc.h" -/* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */ -#ifdef HAVE_SYS_SEM_H -#include <sys/sem.h> -#endif - -#if defined(__darwin__) -#include "port/darwin/sem.h" -#endif - #include "miscadmin.h" #include "access/xact.h" +#include "storage/ipc.h" #include "storage/proc.h" #include "storage/sinval.h" #include "storage/spin.h" @@ -73,11 +58,11 @@ int DeadlockTimeout = 1000; PROC *MyProc = NULL; /* - * This spinlock protects the freelist of recycled PROC structures and the - * bitmap of free semaphores. We cannot use an LWLock because the LWLock - * manager depends on already having a PROC and a wait semaphore! But these - * structures are touched relatively infrequently (only at backend startup - * or shutdown) and not for very long, so a spinlock is okay. + * This spinlock protects the freelist of recycled PROC structures. + * We cannot use an LWLock because the LWLock manager depends on already + * having a PROC and a wait semaphore! But these structures are touched + * relatively infrequently (only at backend startup or shutdown) and not for + * very long, so a spinlock is okay. */ static slock_t *ProcStructLock = NULL; @@ -90,21 +75,24 @@ static bool waitingForSignal = false; static void ProcKill(void); static void DummyProcKill(void); -static void ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum); -static void ProcFreeSem(IpcSemaphoreId semId, int semNum); -static void ZeroProcSemaphore(PROC *proc); -static void ProcFreeAllSemaphores(void); /* + * Report number of semaphores needed by InitProcGlobal. + */ +int +ProcGlobalSemas(int maxBackends) +{ + /* We need a sema per backend, plus one for the dummy process. */ + return maxBackends + 1; +} + +/* * InitProcGlobal - * initializes the global process table. We put it here so that - * the postmaster can do this initialization. (ProcFreeAllSemaphores needs - * to read this table on exiting the postmaster. If we have the first - * backend do this, starting up and killing the postmaster without - * starting any backends will be a problem.) + * the postmaster can do this initialization. * - * We also allocate all the per-process semaphores we will need to support + * We also create all the per-process semaphores we will need to support * the requested number of backends. We used to allocate semaphores * only when backends were actually started up, but that is bad because * it lets Postgres fail under load --- a lot of Unix systems are @@ -114,28 +102,19 @@ static void ProcFreeAllSemaphores(void); * of backends immediately at initialization --- if the sysadmin has set * MaxBackends higher than his kernel will support, he'll find out sooner * rather than later. + * + * Another reason for creating semaphores here is that the semaphore + * implementation typically requires us to create semaphores in the + * postmaster, not in backends. */ void InitProcGlobal(int maxBackends) { - int semMapEntries; - Size procGlobalSize; bool found = false; - /* - * Compute size for ProcGlobal structure. Note we need one more sema - * besides those used for regular backends; this is accounted for in - * the PROC_SEM_MAP_ENTRIES macro. (We do it that way so that other - * modules that use PROC_SEM_MAP_ENTRIES(maxBackends) to size data - * structures don't have to know about this explicitly.) - */ - Assert(maxBackends > 0); - semMapEntries = PROC_SEM_MAP_ENTRIES(maxBackends); - procGlobalSize = sizeof(PROC_HDR) + (semMapEntries - 1) *sizeof(SEM_MAP_ENTRY); - /* Create or attach to the ProcGlobal shared structure */ ProcGlobal = (PROC_HDR *) - ShmemInitStruct("Proc Header", procGlobalSize, &found); + ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found); /* -------------------- * We're the first - initialize. @@ -148,47 +127,33 @@ InitProcGlobal(int maxBackends) int i; ProcGlobal->freeProcs = INVALID_OFFSET; - ProcGlobal->semMapEntries = semMapEntries; - - for (i = 0; i < semMapEntries; i++) - { - ProcGlobal->procSemMap[i].procSemId = -1; - ProcGlobal->procSemMap[i].freeSemMap = 0; - } - - /* - * Arrange to delete semas on exit --- set this up now so that we - * will clean up if pre-allocation fails. We use our own - * freeproc, rather than IpcSemaphoreCreate's removeOnExit option, - * because we don't want to fill up the on_shmem_exit list with a - * separate entry for each semaphore set. - */ - on_shmem_exit(ProcFreeAllSemaphores, 0); /* - * Pre-create the semaphores. + * Pre-create the PROC structures and create a semaphore for each. */ - for (i = 0; i < semMapEntries; i++) + for (i = 0; i < maxBackends; i++) { - IpcSemaphoreId semId; - - semId = IpcSemaphoreCreate(PROC_NSEMS_PER_SET, - IPCProtection, - 1, - false); - ProcGlobal->procSemMap[i].procSemId = semId; + PROC *proc; + + proc = (PROC *) ShmemAlloc(sizeof(PROC)); + if (!proc) + elog(FATAL, "cannot create new proc: out of memory"); + MemSet(proc, 0, sizeof(PROC)); + PGSemaphoreCreate(&proc->sem); + proc->links.next = ProcGlobal->freeProcs; + ProcGlobal->freeProcs = MAKE_OFFSET(proc); } /* * Pre-allocate a PROC structure for dummy (checkpoint) processes, - * and reserve the last sema of the precreated semas for it. + * too. This does not get linked into the freeProcs list. */ DummyProc = (PROC *) ShmemAlloc(sizeof(PROC)); + if (!DummyProc) + elog(FATAL, "cannot create new proc: out of memory"); + MemSet(DummyProc, 0, sizeof(PROC)); DummyProc->pid = 0; /* marks DummyProc as not in use */ - i = semMapEntries - 1; - ProcGlobal->procSemMap[i].freeSemMap |= 1 << (PROC_NSEMS_PER_SET - 1); - DummyProc->sem.semId = ProcGlobal->procSemMap[i].procSemId; - DummyProc->sem.semNum = PROC_NSEMS_PER_SET - 1; + PGSemaphoreCreate(&DummyProc->sem); /* Create ProcStructLock spinlock, too */ ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t)); @@ -197,7 +162,7 @@ InitProcGlobal(int maxBackends) } /* - * InitProcess -- create a per-process data structure for this backend + * InitProcess -- initialize a per-process data structure for this backend */ void InitProcess(void) @@ -217,7 +182,8 @@ InitProcess(void) elog(ERROR, "InitProcess: you already exist"); /* - * try to get a proc struct from the free list first + * Try to get a proc struct from the free list. If this fails, + * we must be out of PROC structures (not to mention semaphores). */ SpinLockAcquire(ProcStructLock); @@ -232,20 +198,19 @@ InitProcess(void) else { /* - * have to allocate a new one. + * If we reach here, all the PROCs are in use. This is one of + * the possible places to detect "too many backends", so give the + * standard error message. */ SpinLockRelease(ProcStructLock); - MyProc = (PROC *) ShmemAlloc(sizeof(PROC)); - if (!MyProc) - elog(FATAL, "cannot create new proc: out of memory"); + elog(FATAL, "Sorry, too many clients already"); } /* - * Initialize all fields of MyProc. + * Initialize all fields of MyProc, except for the semaphore which + * was prepared for us by InitProcGlobal. */ SHMQueueElemInit(&(MyProc->links)); - MyProc->sem.semId = -1; /* no wait-semaphore acquired yet */ - MyProc->sem.semNum = -1; MyProc->errType = STATUS_OK; MyProc->xid = InvalidTransactionId; MyProc->xmin = InvalidTransactionId; @@ -265,18 +230,10 @@ InitProcess(void) on_shmem_exit(ProcKill, 0); /* - * Set up a wait-semaphore for the proc. (We rely on ProcKill to - * clean up MyProc if this fails.) - */ - if (IsUnderPostmaster) - ProcGetNewSemIdAndNum(&MyProc->sem.semId, &MyProc->sem.semNum); - - /* * We might be reusing a semaphore that belonged to a failed process. * So be careful and reinitialize its value here. */ - if (MyProc->sem.semId >= 0) - ZeroProcSemaphore(MyProc); + PGSemaphoreReset(&MyProc->sem); /* * Now that we have a PROC, we could try to acquire locks, so @@ -340,25 +297,7 @@ InitDummyProcess(void) * We might be reusing a semaphore that belonged to a failed process. * So be careful and reinitialize its value here. */ - if (MyProc->sem.semId >= 0) - ZeroProcSemaphore(MyProc); -} - -/* - * Initialize the proc's wait-semaphore to count zero. - */ -static void -ZeroProcSemaphore(PROC *proc) -{ - union semun semun; - - semun.val = 0; - if (semctl(proc->sem.semId, proc->sem.semNum, SETVAL, semun) < 0) - { - fprintf(stderr, "ZeroProcSemaphore: semctl(id=%d,SETVAL) failed: %s\n", - proc->sem.semId, strerror(errno)); - proc_exit(255); - } + PGSemaphoreReset(&MyProc->sem); } /* @@ -397,7 +336,7 @@ LockWaitCancel(void) * to zero. Otherwise, our next attempt to wait for a lock will fall * through prematurely. */ - ZeroProcSemaphore(MyProc); + PGSemaphoreReset(&MyProc->sem); /* * Return true even if we were kicked off the lock before we were able @@ -463,11 +402,7 @@ ProcKill(void) SpinLockAcquire(ProcStructLock); - /* Free up my wait semaphore, if I got one */ - if (MyProc->sem.semId >= 0) - ProcFreeSem(MyProc->sem.semId, MyProc->sem.semNum); - - /* Add PROC struct to freelist so space can be recycled in future */ + /* Return PROC structure (and semaphore) to freelist */ MyProc->links.next = procglobal->freeProcs; procglobal->freeProcs = MAKE_OFFSET(MyProc); @@ -701,10 +636,10 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable, elog(FATAL, "ProcSleep: Unable to set timer for process wakeup"); /* - * If someone wakes us between LWLockRelease and IpcSemaphoreLock, - * IpcSemaphoreLock will not block. The wakeup is "saved" by the + * If someone wakes us between LWLockRelease and PGSemaphoreLock, + * PGSemaphoreLock will not block. The wakeup is "saved" by the * semaphore implementation. Note also that if HandleDeadLock is - * invoked but does not detect a deadlock, IpcSemaphoreLock() will + * invoked but does not detect a deadlock, PGSemaphoreLock() will * continue to wait. There used to be a loop here, but it was useless * code... * @@ -714,7 +649,7 @@ ProcSleep(LOCKMETHODTABLE *lockMethodTable, * here. We don't, because we have no state-change work to do after * being granted the lock (the grantor did it all). */ - IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum, true); + PGSemaphoreLock(&MyProc->sem, true); /* * Disable the timer, if it's still running @@ -775,7 +710,7 @@ ProcWakeup(PROC *proc, int errType) proc->errType = errType; /* And awaken it */ - IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum); + PGSemaphoreUnlock(&proc->sem); return retProc; } @@ -914,7 +849,7 @@ HandleDeadLock(SIGNAL_ARGS) * Unlock my semaphore so that the interrupted ProcSleep() call can * finish. */ - IpcSemaphoreUnlock(MyProc->sem.semId, MyProc->sem.semNum); + PGSemaphoreUnlock(&MyProc->sem); /* * We're done here. Transaction abort caused by the error that @@ -943,7 +878,7 @@ void ProcWaitForSignal(void) { waitingForSignal = true; - IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum, true); + PGSemaphoreLock(&MyProc->sem, true); waitingForSignal = false; } @@ -957,7 +892,7 @@ ProcWaitForSignal(void) void ProcCancelWaitForSignal(void) { - ZeroProcSemaphore(MyProc); + PGSemaphoreReset(&MyProc->sem); waitingForSignal = false; } @@ -970,7 +905,7 @@ ProcSendSignal(BackendId procId) PROC *proc = BackendIdGetProc(procId); if (proc != NULL) - IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum); + PGSemaphoreUnlock(&proc->sem); } @@ -1035,110 +970,3 @@ disable_sigalrm_interrupt(void) return true; } - - -/***************************************************************************** - * - *****************************************************************************/ - -/* - * ProcGetNewSemIdAndNum - - * scan the free semaphore bitmap and allocate a single semaphore from - * a semaphore set. - */ -static void -ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum) -{ - /* use volatile pointer to prevent code rearrangement */ - volatile PROC_HDR *procglobal = ProcGlobal; - int semMapEntries = procglobal->semMapEntries; - volatile SEM_MAP_ENTRY *procSemMap = procglobal->procSemMap; - int32 fullmask = (1 << PROC_NSEMS_PER_SET) - 1; - int i; - - SpinLockAcquire(ProcStructLock); - - for (i = 0; i < semMapEntries; i++) - { - int mask = 1; - int j; - - if (procSemMap[i].freeSemMap == fullmask) - continue; /* this set is fully allocated */ - if (procSemMap[i].procSemId < 0) - continue; /* this set hasn't been initialized */ - - for (j = 0; j < PROC_NSEMS_PER_SET; j++) - { - if ((procSemMap[i].freeSemMap & mask) == 0) - { - /* A free semaphore found. Mark it as allocated. */ - procSemMap[i].freeSemMap |= mask; - - *semId = procSemMap[i].procSemId; - *semNum = j; - - SpinLockRelease(ProcStructLock); - - return; - } - mask <<= 1; - } - } - - SpinLockRelease(ProcStructLock); - - /* - * If we reach here, all the semaphores are in use. This is one of - * the possible places to detect "too many backends", so give the - * standard error message. (Whether we detect it here or in sinval.c - * depends on whether MaxBackends is a multiple of - * PROC_NSEMS_PER_SET.) - */ - elog(FATAL, "Sorry, too many clients already"); -} - -/* - * ProcFreeSem - - * free up our semaphore in the semaphore set. - * - * Caller is assumed to hold ProcStructLock. - */ -static void -ProcFreeSem(IpcSemaphoreId semId, int semNum) -{ - int32 mask; - int i; - int semMapEntries = ProcGlobal->semMapEntries; - - mask = ~(1 << semNum); - - for (i = 0; i < semMapEntries; i++) - { - if (ProcGlobal->procSemMap[i].procSemId == semId) - { - ProcGlobal->procSemMap[i].freeSemMap &= mask; - return; - } - } - /* can't elog here!!! */ - fprintf(stderr, "ProcFreeSem: no ProcGlobal entry for semId %d\n", semId); -} - -/* - * ProcFreeAllSemaphores - - * called at shmem_exit time, ie when exiting the postmaster or - * destroying shared state for a failed set of backends. - * Free up all the semaphores allocated to the lmgrs of the backends. - */ -static void -ProcFreeAllSemaphores(void) -{ - int i; - - for (i = 0; i < ProcGlobal->semMapEntries; i++) - { - if (ProcGlobal->procSemMap[i].procSemId >= 0) - IpcSemaphoreKill(ProcGlobal->procSemMap[i].procSemId); - } -} diff --git a/src/backend/storage/lmgr/spin.c b/src/backend/storage/lmgr/spin.c index f5bb8e34889..c384c4b1586 100644 --- a/src/backend/storage/lmgr/spin.c +++ b/src/backend/storage/lmgr/spin.c @@ -6,7 +6,8 @@ * * For machines that have test-and-set (TAS) instructions, s_lock.h/.c * define the spinlock implementation. This file contains only a stub - * implementation for spinlocks using SysV semaphores. The semaphore method + * implementation for spinlocks using PGSemaphores. Unless semaphores + * are implemented in a way that doesn't involve a kernel call, this * is too slow to be very useful :-( * * @@ -15,143 +16,49 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/spin.c,v 1.7 2001/11/05 17:46:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/spin.c,v 1.8 2002/05/05 00:03:28 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" -#include <errno.h> - -#include "storage/ipc.h" -/* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */ -#ifdef HAVE_SYS_SEM_H -#include <sys/sem.h> -#endif - -#if defined(__darwin__) -#include "port/darwin/sem.h" -#endif - #include "storage/lwlock.h" -#include "storage/proc.h" +#include "storage/pg_sema.h" #include "storage/spin.h" #ifdef HAS_TEST_AND_SET /* - * CreateSpinlocks --- create and initialize spinlocks during startup + * Report number of semaphores needed to support spinlocks. */ -void -CreateSpinlocks(void) +int +SpinlockSemas(void) { - /* no-op when we have TAS spinlocks */ + return 0; } #else /* !HAS_TEST_AND_SET */ /* - * No TAS, so spinlocks are implemented using SysV semaphores. - * - * Typedef slock_t stores the semId and sem number of the sema to use. - * The semas needed are created by CreateSpinlocks and doled out by - * s_init_lock_sema. - * - * Since many systems have a rather small SEMMSL limit on semas per set, - * we allocate the semaphores required in sets of SPINLOCKS_PER_SET semas. - * This value is deliberately made equal to PROC_NSEMS_PER_SET so that all - * sema sets allocated by Postgres will be the same size; that eases the - * semaphore-recycling logic in IpcSemaphoreCreate(). - * - * Note that the SpinLockIds array is not in shared memory; it is filled - * by the postmaster and then inherited through fork() by backends. This - * is OK because its contents do not change after shmem initialization. + * No TAS, so spinlocks are implemented as PGSemaphores. */ -#define SPINLOCKS_PER_SET PROC_NSEMS_PER_SET - -static IpcSemaphoreId *SpinLockIds = NULL; - -static int numSpinSets = 0; /* number of sema sets used */ -static int numSpinLocks = 0; /* total number of semas allocated */ -static int nextSpinLock = 0; /* next free spinlock index */ - -static void SpinFreeAllSemaphores(void); - /* - * CreateSpinlocks --- create and initialize spinlocks during startup + * Report number of semaphores needed to support spinlocks. */ -void -CreateSpinlocks(void) +int +SpinlockSemas(void) { - int i; - - if (SpinLockIds == NULL) - { - /* - * Compute number of spinlocks needed. It would be cleaner to - * distribute this logic into the affected modules, similar to the - * way shmem space estimation is handled. - * - * For now, though, we just need a few spinlocks (10 should be - * plenty) plus one for each LWLock. - */ - numSpinLocks = NumLWLocks() + 10; - - /* might as well round up to a multiple of SPINLOCKS_PER_SET */ - numSpinSets = (numSpinLocks - 1) / SPINLOCKS_PER_SET + 1; - numSpinLocks = numSpinSets * SPINLOCKS_PER_SET; - - SpinLockIds = (IpcSemaphoreId *) - malloc(numSpinSets * sizeof(IpcSemaphoreId)); - Assert(SpinLockIds != NULL); - } - - for (i = 0; i < numSpinSets; i++) - SpinLockIds[i] = -1; - /* - * Arrange to delete semas on exit --- set this up now so that we will - * clean up if allocation fails. We use our own freeproc, rather than - * IpcSemaphoreCreate's removeOnExit option, because we don't want to - * fill up the on_shmem_exit list with a separate entry for each - * semaphore set. + * It would be cleaner to distribute this logic into the affected modules, + * similar to the way shmem space estimation is handled. + * + * For now, though, we just need a few spinlocks (10 should be + * plenty) plus one for each LWLock. */ - on_shmem_exit(SpinFreeAllSemaphores, 0); - - /* Create sema sets and set all semas to count 1 */ - for (i = 0; i < numSpinSets; i++) - { - SpinLockIds[i] = IpcSemaphoreCreate(SPINLOCKS_PER_SET, - IPCProtection, - 1, - false); - } - - /* Init counter for allocating dynamic spinlocks */ - nextSpinLock = 0; -} - -/* - * SpinFreeAllSemaphores - - * called at shmem_exit time, ie when exiting the postmaster or - * destroying shared state for a failed set of backends. - * Free up all the semaphores allocated for spinlocks. - */ -static void -SpinFreeAllSemaphores(void) -{ - int i; - - for (i = 0; i < numSpinSets; i++) - { - if (SpinLockIds[i] >= 0) - IpcSemaphoreKill(SpinLockIds[i]); - } - free(SpinLockIds); - SpinLockIds = NULL; + return NumLWLocks() + 10; } /* @@ -161,30 +68,28 @@ SpinFreeAllSemaphores(void) void s_init_lock_sema(volatile slock_t *lock) { - if (nextSpinLock >= numSpinLocks) - elog(FATAL, "s_init_lock_sema: not enough semaphores"); - lock->semId = SpinLockIds[nextSpinLock / SPINLOCKS_PER_SET]; - lock->sem = nextSpinLock % SPINLOCKS_PER_SET; - nextSpinLock++; + PGSemaphoreCreate((PGSemaphore) lock); } void s_unlock_sema(volatile slock_t *lock) { - IpcSemaphoreUnlock(lock->semId, lock->sem); + PGSemaphoreUnlock((PGSemaphore) lock); } bool s_lock_free_sema(volatile slock_t *lock) { - return IpcSemaphoreGetValue(lock->semId, lock->sem) > 0; + /* We don't currently use S_LOCK_FREE anyway */ + elog(ERROR, "spin.c does not support S_LOCK_FREE()"); + return false; } int tas_sema(volatile slock_t *lock) { /* Note that TAS macros return 0 if *success* */ - return !IpcSemaphoreTryLock(lock->semId, lock->sem); + return !PGSemaphoreTryLock((PGSemaphore) lock); } #endif /* !HAS_TEST_AND_SET */ |