Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 11635c3

Browse files
author
Neil Conway
committed
Refactor some duplicated code in lock.c: create UnGrantLock(), move code
from LockRelease() and LockReleaseAll() into it. From Heikki Linnakangas.
1 parent ee467c3 commit 11635c3

File tree

1 file changed

+65
-56
lines changed
  • src/backend/storage/lmgr

1 file changed

+65
-56
lines changed

src/backend/storage/lmgr/lock.c

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.145 2004/12/31 22:01:05 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.146 2005/02/04 02:04:53 neilc Exp $
1212
*
1313
* NOTES
1414
* Outside modules can create a lock table and acquire/release
@@ -166,6 +166,8 @@ static int WaitOnLock(LOCKMETHODID lockmethodid, LOCALLOCK *locallock,
166166
ResourceOwner owner);
167167
static void LockCountMyLocks(SHMEM_OFFSET lockOffset, PGPROC *proc,
168168
int *myHolding);
169+
static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode,
170+
PROCLOCK *proclock, LockMethod lockMethodTable);
169171

170172

171173
/*
@@ -957,6 +959,65 @@ GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
957959
Assert(lock->nGranted <= lock->nRequested);
958960
}
959961

962+
/*
963+
* UnGrantLock -- opposite of GrantLock.
964+
*
965+
* Updates the lock and proclock data structures to show that the lock
966+
* is no longer held nor requested by the current holder.
967+
*
968+
* Returns true if there were any waiters waiting on the lock that
969+
* should now be woken up with ProcLockWakeup.
970+
*/
971+
static bool
972+
UnGrantLock(LOCK *lock, LOCKMODE lockmode,
973+
PROCLOCK *proclock, LockMethod lockMethodTable)
974+
{
975+
bool wakeupNeeded = false;
976+
977+
Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
978+
Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
979+
Assert(lock->nGranted <= lock->nRequested);
980+
981+
/*
982+
* fix the general lock stats
983+
*/
984+
lock->nRequested--;
985+
lock->requested[lockmode]--;
986+
lock->nGranted--;
987+
lock->granted[lockmode]--;
988+
989+
if (lock->granted[lockmode] == 0)
990+
{
991+
/* change the conflict mask. No more of this lock type. */
992+
lock->grantMask &= LOCKBIT_OFF(lockmode);
993+
}
994+
995+
LOCK_PRINT("UnGrantLock: updated", lock, lockmode);
996+
Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
997+
Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
998+
Assert(lock->nGranted <= lock->nRequested);
999+
1000+
/*
1001+
* We need only run ProcLockWakeup if the released lock conflicts with
1002+
* at least one of the lock types requested by waiter(s). Otherwise
1003+
* whatever conflict made them wait must still exist. NOTE: before
1004+
* MVCC, we could skip wakeup if lock->granted[lockmode] was still
1005+
* positive. But that's not true anymore, because the remaining
1006+
* granted locks might belong to some waiter, who could now be
1007+
* awakened because he doesn't conflict with his own locks.
1008+
*/
1009+
if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
1010+
wakeupNeeded = true;
1011+
1012+
/*
1013+
* Now fix the per-proclock state.
1014+
*/
1015+
proclock->holdMask &= LOCKBIT_OFF(lockmode);
1016+
PROCLOCK_PRINT("UnGrantLock: updated", proclock);
1017+
1018+
return wakeupNeeded;
1019+
}
1020+
9601021
/*
9611022
* GrantLockLocal -- update the locallock data structures to show
9621023
* the lock request has been granted.
@@ -1265,46 +1326,8 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
12651326
RemoveLocalLock(locallock);
12661327
return FALSE;
12671328
}
1268-
Assert((lock->nRequested > 0) && (lock->requested[lockmode] > 0));
1269-
Assert((lock->nGranted > 0) && (lock->granted[lockmode] > 0));
1270-
Assert(lock->nGranted <= lock->nRequested);
1271-
1272-
/*
1273-
* fix the general lock stats
1274-
*/
1275-
lock->nRequested--;
1276-
lock->requested[lockmode]--;
1277-
lock->nGranted--;
1278-
lock->granted[lockmode]--;
1279-
1280-
if (lock->granted[lockmode] == 0)
1281-
{
1282-
/* change the conflict mask. No more of this lock type. */
1283-
lock->grantMask &= LOCKBIT_OFF(lockmode);
1284-
}
1285-
1286-
LOCK_PRINT("LockRelease: updated", lock, lockmode);
1287-
Assert((lock->nRequested >= 0) && (lock->requested[lockmode] >= 0));
1288-
Assert((lock->nGranted >= 0) && (lock->granted[lockmode] >= 0));
1289-
Assert(lock->nGranted <= lock->nRequested);
1290-
1291-
/*
1292-
* We need only run ProcLockWakeup if the released lock conflicts with
1293-
* at least one of the lock types requested by waiter(s). Otherwise
1294-
* whatever conflict made them wait must still exist. NOTE: before
1295-
* MVCC, we could skip wakeup if lock->granted[lockmode] was still
1296-
* positive. But that's not true anymore, because the remaining
1297-
* granted locks might belong to some waiter, who could now be
1298-
* awakened because he doesn't conflict with his own locks.
1299-
*/
1300-
if (lockMethodTable->conflictTab[lockmode] & lock->waitMask)
1301-
wakeupNeeded = true;
13021329

1303-
/*
1304-
* Now fix the per-proclock state.
1305-
*/
1306-
proclock->holdMask &= LOCKBIT_OFF(lockmode);
1307-
PROCLOCK_PRINT("LockRelease: updated", proclock);
1330+
wakeupNeeded = UnGrantLock(lock, lockmode, proclock, lockMethodTable);
13081331

13091332
/*
13101333
* If this was my last hold on this lock, delete my entry in the
@@ -1483,22 +1506,8 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allxids)
14831506
for (i = 1; i <= numLockModes; i++)
14841507
{
14851508
if (proclock->holdMask & LOCKBIT_ON(i))
1486-
{
1487-
lock->requested[i]--;
1488-
lock->granted[i]--;
1489-
Assert(lock->requested[i] >= 0 && lock->granted[i] >= 0);
1490-
if (lock->granted[i] == 0)
1491-
lock->grantMask &= LOCKBIT_OFF(i);
1492-
lock->nRequested--;
1493-
lock->nGranted--;
1494-
1495-
/*
1496-
* Read comments in LockRelease
1497-
*/
1498-
if (!wakeupNeeded &&
1499-
lockMethodTable->conflictTab[i] & lock->waitMask)
1500-
wakeupNeeded = true;
1501-
}
1509+
wakeupNeeded |= UnGrantLock(lock, i, proclock,
1510+
lockMethodTable);
15021511
}
15031512
}
15041513
Assert((lock->nRequested >= 0) && (lock->nGranted >= 0));

0 commit comments

Comments
 (0)