Refactor some duplicated code in lock.c: create UnGrantLock(), move code
from LockRelease() and LockReleaseAll() into it. From Heikki Linnakangas.
This commit is contained in:
parent
ee467c3530
commit
11635c3f6f
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.145 2004/12/31 22:01:05 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.146 2005/02/04 02:04:53 neilc Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Outside modules can create a lock table and acquire/release
|
* Outside modules can create a lock table and acquire/release
|
||||||
|
@ -166,6 +166,8 @@ static int WaitOnLock(LOCKMETHODID lockmethodid, LOCALLOCK *locallock,
|
||||||
ResourceOwner owner);
|
ResourceOwner owner);
|
||||||
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PGPROC *proc,
|
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PGPROC *proc,
|
||||||
int *myHolding);
|
int *myHolding);
|
||||||
|
static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode,
|
||||||
|
PROCLOCK *proclock, LockMethod lockMethodTable);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -957,6 +959,65 @@ GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
|
||||||
Assert(lock->nGranted <= lock->nRequested);
|
Assert(lock->nGranted <= lock->nRequested);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UnGrantLock -- opposite of GrantLock.
|
||||||
|
*
|
||||||
|
* Updates the lock and proclock data structures to show that the lock
|
||||||
|
* is no longer held nor requested by the current holder.
|
||||||
|
*
|
||||||
|
* Returns true if there were any waiters waiting on the lock that
|
||||||
|
* should now be woken up with ProcLockWakeup.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
UnGrantLock(LOCK *lock, LOCKMODE lockmode,
|
||||||
|
PROCLOCK *proclock, LockMethod lockMethodTable)
|
||||||
|
{
|
||||||
|
bool wakeupNeeded = false;
|
||||||
|
|
||||||
|
Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
|
||||||
|
Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
|
||||||
|
Assert(lock->nGranted <= lock->nRequested);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fix the general lock stats
|
||||||
|
*/
|
||||||
|
lock->nRequested--;
|
||||||
|
lock->requested[lockmode]--;
|
||||||
|
lock->nGranted--;
|
||||||
|
lock->granted[lockmode]--;
|
||||||
|
|
||||||
|
if (lock->granted[lockmode] == 0)
|
||||||
|
{
|
||||||
|
/* change the conflict mask. No more of this lock type. */
|
||||||
|
lock->grantMask &= LOCKBIT_OFF(lockmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK_PRINT("UnGrantLock: updated", lock, lockmode);
|
||||||
|
Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
|
||||||
|
Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
|
||||||
|
Assert(lock->nGranted <= lock->nRequested);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need only run ProcLockWakeup if the released lock conflicts with
|
||||||
|
* at least one of the lock types requested by waiter(s). Otherwise
|
||||||
|
* whatever conflict made them wait must still exist. NOTE: before
|
||||||
|
* MVCC, we could skip wakeup if lock->granted[lockmode] was still
|
||||||
|
* positive. But that's not true anymore, because the remaining
|
||||||
|
* granted locks might belong to some waiter, who could now be
|
||||||
|
* awakened because he doesn't conflict with his own locks.
|
||||||
|
*/
|
||||||
|
if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
|
||||||
|
wakeupNeeded = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now fix the per-proclock state.
|
||||||
|
*/
|
||||||
|
proclock->holdMask &= LOCKBIT_OFF(lockmode);
|
||||||
|
PROCLOCK_PRINT("UnGrantLock: updated", proclock);
|
||||||
|
|
||||||
|
return wakeupNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GrantLockLocal -- update the locallock data structures to show
|
* GrantLockLocal -- update the locallock data structures to show
|
||||||
* the lock request has been granted.
|
* the lock request has been granted.
|
||||||
|
@ -1265,46 +1326,8 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
|
||||||
RemoveLocalLock(locallock);
|
RemoveLocalLock(locallock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
|
|
||||||
Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
|
|
||||||
Assert(lock->nGranted <= lock->nRequested);
|
|
||||||
|
|
||||||
/*
|
wakeupNeeded = UnGrantLock(lock, lockmode, proclock, lockMethodTable);
|
||||||
* fix the general lock stats
|
|
||||||
*/
|
|
||||||
lock->nRequested--;
|
|
||||||
lock->requested[lockmode]--;
|
|
||||||
lock->nGranted--;
|
|
||||||
lock->granted[lockmode]--;
|
|
||||||
|
|
||||||
if (lock->granted[lockmode] == 0)
|
|
||||||
{
|
|
||||||
/* change the conflict mask. No more of this lock type. */
|
|
||||||
lock->grantMask &= LOCKBIT_OFF(lockmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK_PRINT("LockRelease: updated", lock, lockmode);
|
|
||||||
Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
|
|
||||||
Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
|
|
||||||
Assert(lock->nGranted <= lock->nRequested);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need only run ProcLockWakeup if the released lock conflicts with
|
|
||||||
* at least one of the lock types requested by waiter(s). Otherwise
|
|
||||||
* whatever conflict made them wait must still exist. NOTE: before
|
|
||||||
* MVCC, we could skip wakeup if lock->granted[lockmode] was still
|
|
||||||
* positive. But that's not true anymore, because the remaining
|
|
||||||
* granted locks might belong to some waiter, who could now be
|
|
||||||
* awakened because he doesn't conflict with his own locks.
|
|
||||||
*/
|
|
||||||
if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
|
|
||||||
wakeupNeeded = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now fix the per-proclock state.
|
|
||||||
*/
|
|
||||||
proclock->holdMask &= LOCKBIT_OFF(lockmode);
|
|
||||||
PROCLOCK_PRINT("LockRelease: updated", proclock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this was my last hold on this lock, delete my entry in the
|
* If this was my last hold on this lock, delete my entry in the
|
||||||
|
@ -1483,22 +1506,8 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
|
||||||
for (i = 1; i <= numLockModes; i++)
|
for (i = 1; i <= numLockModes; i++)
|
||||||
{
|
{
|
||||||
if (proclock->holdMask & LOCKBIT_ON(i))
|
if (proclock->holdMask & LOCKBIT_ON(i))
|
||||||
{
|
wakeupNeeded |= UnGrantLock(lock, i, proclock,
|
||||||
lock->requested[i]--;
|
lockMethodTable);
|
||||||
lock->granted[i]--;
|
|
||||||
Assert(lock->requested[i] >= 0 && lock->granted[i] >= 0);
|
|
||||||
if (lock->granted[i] == 0)
|
|
||||||
lock->grantMask &= LOCKBIT_OFF(i);
|
|
||||||
lock->nRequested--;
|
|
||||||
lock->nGranted--;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read comments in LockRelease
|
|
||||||
*/
|
|
||||||
if (!wakeupNeeded &&
|
|
||||||
lockMethodTable->conflictTab[i] & lock->waitMask)
|
|
||||||
wakeupNeeded = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assert((lock->nRequested >= 0) && (lock->nGranted >= 0));
|
Assert((lock->nRequested >= 0) && (lock->nGranted >= 0));
|
||||||
|
|
Loading…
Reference in New Issue