aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/lmgr/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/lmgr/proc.c')
-rw-r--r--src/backend/storage/lmgr/proc.c225
1 files changed, 109 insertions, 116 deletions
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 6005cb7ee53..1c26a5934ba 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.166 2005/10/13 06:24:05 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.167 2005/10/15 02:49:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -166,8 +166,7 @@ InitProcGlobal(void)
ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
/*
- * Pre-create the PGPROC structures and create a semaphore for
- * each.
+ * Pre-create the PGPROC structures and create a semaphore for each.
*/
procs = (PGPROC *) ShmemAlloc(MaxBackends * sizeof(PGPROC));
if (!procs)
@@ -207,8 +206,8 @@ InitProcess(void)
volatile PROC_HDR *procglobal = ProcGlobal;
/*
- * ProcGlobal should be set by a previous call to InitProcGlobal (if
- * we are a backend, we inherit this by fork() from the postmaster).
+ * ProcGlobal should be set by a previous call to InitProcGlobal (if we
+ * are a backend, we inherit this by fork() from the postmaster).
*/
if (procglobal == NULL)
elog(PANIC, "proc header uninitialized");
@@ -217,11 +216,11 @@ InitProcess(void)
elog(ERROR, "you already exist");
/*
- * Try to get a proc struct from the free list. If this fails, we
- * must be out of PGPROC structures (not to mention semaphores).
+ * Try to get a proc struct from the free list. If this fails, we must be
+ * out of PGPROC structures (not to mention semaphores).
*
- * While we are holding the ProcStructLock, also copy the current
- * shared estimate of spins_per_delay to local storage.
+ * While we are holding the ProcStructLock, also copy the current shared
+ * estimate of spins_per_delay to local storage.
*/
SpinLockAcquire(ProcStructLock);
@@ -238,9 +237,9 @@ InitProcess(void)
else
{
/*
- * If we reach here, all the PGPROCs are in use. This is one of
- * the possible places to detect "too many backends", so give the
- * standard error message.
+ * If we reach here, all the PGPROCs are in use. This is one of the
+ * possible places to detect "too many backends", so give the standard
+ * error message.
*/
SpinLockRelease(ProcStructLock);
ereport(FATAL,
@@ -278,14 +277,14 @@ InitProcess(void)
on_shmem_exit(ProcKill, 0);
/*
- * We might be reusing a semaphore that belonged to a failed process.
- * So be careful and reinitialize its value here.
+ * We might be reusing a semaphore that belonged to a failed process. So
+ * be careful and reinitialize its value here.
*/
PGSemaphoreReset(&MyProc->sem);
/*
- * Now that we have a PGPROC, we could try to acquire locks, so
- * initialize the deadlock checker.
+ * Now that we have a PGPROC, we could try to acquire locks, so initialize
+ * the deadlock checker.
*/
InitDeadLockChecking();
}
@@ -322,8 +321,8 @@ InitDummyProcess(int proctype)
* Just for paranoia's sake, we use the ProcStructLock to protect
* assignment and releasing of DummyProcs entries.
*
- * While we are holding the ProcStructLock, also copy the current
- * shared estimate of spins_per_delay to local storage.
+ * While we are holding the ProcStructLock, also copy the current shared
+ * estimate of spins_per_delay to local storage.
*/
SpinLockAcquire(ProcStructLock);
@@ -347,8 +346,8 @@ InitDummyProcess(int proctype)
SpinLockRelease(ProcStructLock);
/*
- * Initialize all fields of MyProc, except MyProc->sem which was set
- * up by InitProcGlobal.
+ * Initialize all fields of MyProc, except MyProc->sem which was set up by
+ * InitProcGlobal.
*/
SHMQueueElemInit(&(MyProc->links));
MyProc->waitStatus = STATUS_OK;
@@ -369,8 +368,8 @@ InitDummyProcess(int proctype)
on_shmem_exit(DummyProcKill, Int32GetDatum(proctype));
/*
- * We might be reusing a semaphore that belonged to a failed process.
- * So be careful and reinitialize its value here.
+ * We might be reusing a semaphore that belonged to a failed process. So
+ * be careful and reinitialize its value here.
*/
PGSemaphoreReset(&MyProc->sem);
}
@@ -385,6 +384,7 @@ HaveNFreeProcs(int n)
{
SHMEM_OFFSET offset;
PGPROC *proc;
+
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
@@ -436,9 +436,9 @@ LockWaitCancel(void)
{
/*
* Somebody kicked us off the lock queue already. Perhaps they
- * granted us the lock, or perhaps they detected a deadlock. If
- * they did grant us the lock, we'd better remember it in our
- * local lock table.
+ * granted us the lock, or perhaps they detected a deadlock. If they
+ * did grant us the lock, we'd better remember it in our local lock
+ * table.
*/
if (MyProc->waitStatus == STATUS_OK)
GrantAwaitedLock();
@@ -451,17 +451,17 @@ LockWaitCancel(void)
/*
* Reset the proc wait semaphore to zero. This is necessary in the
* scenario where someone else granted us the lock we wanted before we
- * were able to remove ourselves from the wait-list. The semaphore
- * will have been bumped to 1 by the would-be grantor, and since we
- * are no longer going to wait on the sema, we have to force it back
- * to zero. Otherwise, our next attempt to wait for a lock will fall
- * through prematurely.
+ * were able to remove ourselves from the wait-list. The semaphore will
+ * have been bumped to 1 by the would-be grantor, and since we are no
+ * longer going to wait on the sema, we have to force it back to zero.
+ * Otherwise, our next attempt to wait for a lock will fall through
+ * prematurely.
*/
PGSemaphoreReset(&MyProc->sem);
/*
- * Return true even if we were kicked off the lock before we were able
- * to remove ourselves.
+ * Return true even if we were kicked off the lock before we were able to
+ * remove ourselves.
*/
return true;
}
@@ -508,8 +508,8 @@ ProcKill(int code, Datum arg)
Assert(MyProc != NULL);
/*
- * Release any LW locks I am holding. There really shouldn't be any,
- * but it's cheap to check again before we cut the knees off the LWLock
+ * Release any LW locks I am holding. There really shouldn't be any, but
+ * it's cheap to check again before we cut the knees off the LWLock
* facility by releasing our PGPROC ...
*/
LWLockReleaseAll();
@@ -640,20 +640,19 @@ ProcSleep(LockMethod lockMethodTable,
/*
* Determine where to add myself in the wait queue.
*
- * Normally I should go at the end of the queue. However, if I already
- * hold locks that conflict with the request of any previous waiter,
- * put myself in the queue just in front of the first such waiter.
- * This is not a necessary step, since deadlock detection would move
- * me to before that waiter anyway; but it's relatively cheap to
- * detect such a conflict immediately, and avoid delaying till
- * deadlock timeout.
+ * Normally I should go at the end of the queue. However, if I already hold
+ * locks that conflict with the request of any previous waiter, put myself
+ * in the queue just in front of the first such waiter. This is not a
+ * necessary step, since deadlock detection would move me to before that
+ * waiter anyway; but it's relatively cheap to detect such a conflict
+ * immediately, and avoid delaying till deadlock timeout.
*
- * Special case: if I find I should go in front of some waiter, check to
- * see if I conflict with already-held locks or the requests before
- * that waiter. If not, then just grant myself the requested lock
- * immediately. This is the same as the test for immediate grant in
- * LockAcquire, except we are only considering the part of the wait
- * queue before my insertion point.
+ * Special case: if I find I should go in front of some waiter, check to see
+ * if I conflict with already-held locks or the requests before that
+ * waiter. If not, then just grant myself the requested lock immediately.
+ * This is the same as the test for immediate grant in LockAcquire, except
+ * we are only considering the part of the wait queue before my insertion
+ * point.
*/
if (myHeldLocks != 0)
{
@@ -669,12 +668,11 @@ ProcSleep(LockMethod lockMethodTable,
if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
{
/*
- * Yes, so we have a deadlock. Easiest way to clean
- * up correctly is to call RemoveFromWaitQueue(), but
- * we can't do that until we are *on* the wait queue.
- * So, set a flag to check below, and break out of
- * loop. Also, record deadlock info for later
- * message.
+ * Yes, so we have a deadlock. Easiest way to clean up
+ * correctly is to call RemoveFromWaitQueue(), but we
+ * can't do that until we are *on* the wait queue. So, set
+ * a flag to check below, and break out of loop. Also,
+ * record deadlock info for later message.
*/
RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
early_deadlock = true;
@@ -702,8 +700,8 @@ ProcSleep(LockMethod lockMethodTable,
}
/*
- * If we fall out of loop normally, proc points to waitQueue head,
- * so we will insert at tail of queue as desired.
+ * If we fall out of loop normally, proc points to waitQueue head, so
+ * we will insert at tail of queue as desired.
*/
}
else
@@ -713,8 +711,7 @@ ProcSleep(LockMethod lockMethodTable,
}
/*
- * Insert self into queue, ahead of the given proc (or at tail of
- * queue).
+ * Insert self into queue, ahead of the given proc (or at tail of queue).
*/
SHMQueueInsertBefore(&(proc->links), &(MyProc->links));
waitQueue->size++;
@@ -729,9 +726,9 @@ ProcSleep(LockMethod lockMethodTable,
MyProc->waitStatus = STATUS_ERROR; /* initialize result for error */
/*
- * If we detected deadlock, give up without waiting. This must agree
- * with CheckDeadLock's recovery code, except that we shouldn't
- * release the semaphore since we haven't tried to lock it yet.
+ * If we detected deadlock, give up without waiting. This must agree with
+ * CheckDeadLock's recovery code, except that we shouldn't release the
+ * semaphore since we haven't tried to lock it yet.
*/
if (early_deadlock)
{
@@ -746,39 +743,38 @@ ProcSleep(LockMethod lockMethodTable,
* Release the locktable's masterLock.
*
* NOTE: this may also cause us to exit critical-section state, possibly
- * allowing a cancel/die interrupt to be accepted. This is OK because
- * we have recorded the fact that we are waiting for a lock, and so
+ * allowing a cancel/die interrupt to be accepted. This is OK because we
+ * have recorded the fact that we are waiting for a lock, and so
* LockWaitCancel will clean up if cancel/die happens.
*/
LWLockRelease(masterLock);
/*
- * Set timer so we can wake up after awhile and check for a deadlock.
- * If a deadlock is detected, the handler releases the process's
- * semaphore and sets MyProc->waitStatus = STATUS_ERROR, allowing us
- * to know that we must report failure rather than success.
+ * Set timer so we can wake up after awhile and check for a deadlock. If a
+ * deadlock is detected, the handler releases the process's semaphore and
+ * sets MyProc->waitStatus = STATUS_ERROR, allowing us to know that we
+ * must report failure rather than success.
*
- * By delaying the check until we've waited for a bit, we can avoid
- * running the rather expensive deadlock-check code in most cases.
+ * By delaying the check until we've waited for a bit, we can avoid running
+ * the rather expensive deadlock-check code in most cases.
*/
if (!enable_sig_alarm(DeadlockTimeout, false))
elog(FATAL, "could not set timer for process wakeup");
/*
* If someone wakes us between LWLockRelease and PGSemaphoreLock,
- * PGSemaphoreLock will not block. The wakeup is "saved" by the
- * semaphore implementation. Note also that if CheckDeadLock is
- * invoked but does not detect a deadlock, PGSemaphoreLock() will
- * continue to wait. There used to be a loop here, but it was useless
- * code...
+ * PGSemaphoreLock will not block. The wakeup is "saved" by the semaphore
+ * implementation. Note also that if CheckDeadLock is invoked but does
+ * not detect a deadlock, PGSemaphoreLock() will continue to wait. There
+ * used to be a loop here, but it was useless code...
*
- * We pass interruptOK = true, which eliminates a window in which
- * cancel/die interrupts would be held off undesirably. This is a
- * promise that we don't mind losing control to a cancel/die interrupt
- * here. We don't, because we have no shared-state-change work to do
- * after being granted the lock (the grantor did it all). We do have
- * to worry about updating the locallock table, but if we lose control
- * to an error, LockWaitCancel will fix that up.
+ * We pass interruptOK = true, which eliminates a window in which cancel/die
+ * interrupts would be held off undesirably. This is a promise that we
+ * don't mind losing control to a cancel/die interrupt here. We don't,
+ * because we have no shared-state-change work to do after being granted
+ * the lock (the grantor did it all). We do have to worry about updating
+ * the locallock table, but if we lose control to an error, LockWaitCancel
+ * will fix that up.
*/
PGSemaphoreLock(&MyProc->sem, true);
@@ -789,9 +785,9 @@ ProcSleep(LockMethod lockMethodTable,
elog(FATAL, "could not disable timer for process wakeup");
/*
- * Re-acquire the locktable's masterLock. We have to do this to hold
- * off cancel/die interrupts before we can mess with waitingForLock
- * (else we might have a missed or duplicated locallock update).
+ * Re-acquire the locktable's masterLock. We have to do this to hold off
+ * cancel/die interrupts before we can mess with waitingForLock (else we
+ * might have a missed or duplicated locallock update).
*/
LWLockAcquire(masterLock, LW_EXCLUSIVE);
@@ -879,8 +875,8 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
LOCKMODE lockmode = proc->waitLockMode;
/*
- * Waken if (a) doesn't conflict with requests of earlier waiters,
- * and (b) doesn't conflict with already-held locks.
+ * Waken if (a) doesn't conflict with requests of earlier waiters, and
+ * (b) doesn't conflict with already-held locks.
*/
if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
LockCheckConflicts(lockMethodTable,
@@ -894,16 +890,15 @@ ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
proc = ProcWakeup(proc, STATUS_OK);
/*
- * ProcWakeup removes proc from the lock's waiting process
- * queue and returns the next proc in chain; don't use proc's
- * next-link, because it's been cleared.
+ * ProcWakeup removes proc from the lock's waiting process queue
+ * and returns the next proc in chain; don't use proc's next-link,
+ * because it's been cleared.
*/
}
else
{
/*
- * Cannot wake this guy. Remember his request for later
- * checks.
+ * Cannot wake this guy. Remember his request for later checks.
*/
aheadRequests |= LOCKBIT_ON(lockmode);
proc = (PGPROC *) MAKE_PTR(proc->links.next);
@@ -928,22 +923,21 @@ CheckDeadLock(void)
* Acquire locktable lock. Note that the deadlock check interrupt had
* better not be enabled anywhere that this process itself holds the
* locktable lock, else this will wait forever. Also note that
- * LWLockAcquire creates a critical section, so that this routine
- * cannot be interrupted by cancel/die interrupts.
+ * LWLockAcquire creates a critical section, so that this routine cannot
+ * be interrupted by cancel/die interrupts.
*/
LWLockAcquire(LockMgrLock, LW_EXCLUSIVE);
/*
* Check to see if we've been awoken by anyone in the interim.
*
- * If we have we can return and resume our transaction -- happy day.
- * Before we are awoken the process releasing the lock grants it to us
- * so we know that we don't have to wait anymore.
+ * If we have we can return and resume our transaction -- happy day. Before
+ * we are awoken the process releasing the lock grants it to us so we know
+ * that we don't have to wait anymore.
*
* We check by looking to see if we've been unlinked from the wait queue.
- * This is quicker than checking our semaphore's state, since no
- * kernel call is needed, and it is safe because we hold the locktable
- * lock.
+ * This is quicker than checking our semaphore's state, since no kernel
+ * call is needed, and it is safe because we hold the locktable lock.
*/
if (MyProc->links.prev == INVALID_OFFSET ||
MyProc->links.next == INVALID_OFFSET)
@@ -972,8 +966,8 @@ CheckDeadLock(void)
RemoveFromWaitQueue(MyProc);
/*
- * Set MyProc->waitStatus to STATUS_ERROR so that ProcSleep will
- * report an error after we return from the signal handler.
+ * Set MyProc->waitStatus to STATUS_ERROR so that ProcSleep will report an
+ * error after we return from the signal handler.
*/
MyProc->waitStatus = STATUS_ERROR;
@@ -984,14 +978,14 @@ CheckDeadLock(void)
PGSemaphoreUnlock(&MyProc->sem);
/*
- * We're done here. Transaction abort caused by the error that
- * ProcSleep will raise will cause any other locks we hold to be
- * released, thus allowing other processes to wake up; we don't need
- * to do that here. NOTE: an exception is that releasing locks we hold
- * doesn't consider the possibility of waiters that were blocked
- * behind us on the lock we just failed to get, and might now be
- * wakable because we're not in front of them anymore. However,
- * RemoveFromWaitQueue took care of waking up any such processes.
+ * We're done here. Transaction abort caused by the error that ProcSleep
+ * will raise will cause any other locks we hold to be released, thus
+ * allowing other processes to wake up; we don't need to do that here.
+ * NOTE: an exception is that releasing locks we hold doesn't consider the
+ * possibility of waiters that were blocked behind us on the lock we just
+ * failed to get, and might now be wakable because we're not in front of
+ * them anymore. However, RemoveFromWaitQueue took care of waking up any
+ * such processes.
*/
LWLockRelease(LockMgrLock);
}
@@ -1061,7 +1055,6 @@ enable_sig_alarm(int delayms, bool is_statement_timeout)
#ifndef __BEOS__
struct itimerval timeval;
-
#else
bigtime_t time_interval;
#endif
@@ -1092,16 +1085,16 @@ enable_sig_alarm(int delayms, bool is_statement_timeout)
/*
* Begin deadlock timeout with statement-level timeout active
*
- * Here, we want to interrupt at the closer of the two timeout times.
- * If fin_time >= statement_fin_time then we need not touch the
- * existing timer setting; else set up to interrupt at the
- * deadlock timeout time.
+ * Here, we want to interrupt at the closer of the two timeout times. If
+ * fin_time >= statement_fin_time then we need not touch the existing
+ * timer setting; else set up to interrupt at the deadlock timeout
+ * time.
*
* NOTE: in this case it is possible that this routine will be
* interrupted by the previously-set timer alarm. This is okay
- * because the signal handler will do only what it should do
- * according to the state variables. The deadlock checker may get
- * run earlier than normal, but that does no harm.
+ * because the signal handler will do only what it should do according
+ * to the state variables. The deadlock checker may get run earlier
+ * than normal, but that does no harm.
*/
deadlock_timeout_active = true;
if (fin_time.tv_sec > statement_fin_time.tv_sec ||