faster-locallock-scan.patch
application/octet-stream
Filename: faster-locallock-scan.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/lock.c | 26 | 26 |
| src/backend/storage/lmgr/proc.c | 2 | 0 |
| src/include/storage/lock.h | 2 | 0 |
| src/include/storage/proc.h | 1 | 0 |
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 3bb5ce3..9475fe1 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -794,6 +794,7 @@ LockAcquireExtended(const LOCKTAG *locktag,
*/
if (!found)
{
+ dlist_push_head(&MyProc->localLocks, &locallock->procLink);
locallock->lock = NULL;
locallock->proclock = NULL;
locallock->hashcode = LockTagHashCode(&(localtag.lock));
@@ -1320,6 +1321,7 @@ RemoveLocalLock(LOCALLOCK *locallock)
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
}
+ dlist_delete(&locallock->procLink);
if (!hash_search(LockMethodLocalHash,
(void *) &(locallock->tag),
HASH_REMOVE, NULL))
@@ -2088,7 +2090,7 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void
LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
{
- HASH_SEQ_STATUS status;
+ dlist_mutable_iter iter;
LockMethod lockMethodTable;
int i,
numLockModes;
@@ -2126,10 +2128,10 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
* pointers. Fast-path locks are cleaned up during the locallock table
* scan, though.
*/
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
{
+ locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
+
/*
* If the LOCALLOCK entry is unused, we must've run out of shared
* memory while trying to set up this lock. Just forget the local
@@ -2362,16 +2364,16 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
void
LockReleaseSession(LOCKMETHODID lockmethodid)
{
- HASH_SEQ_STATUS status;
+ dlist_mutable_iter iter;
LOCALLOCK *locallock;
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
elog(ERROR, "unrecognized lock method: %d", lockmethodid);
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
{
+ locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
+
/* Ignore items that are not of the specified lock method */
if (LOCALLOCK_LOCKMETHOD(*locallock) != lockmethodid)
continue;
@@ -2394,13 +2396,14 @@ LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)
{
if (locallocks == NULL)
{
- HASH_SEQ_STATUS status;
+ dlist_mutable_iter iter;
LOCALLOCK *locallock;
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
+ {
+ locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
ReleaseLockIfHeld(locallock, false);
+ }
}
else
{
@@ -2493,13 +2496,14 @@ LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)
if (locallocks == NULL)
{
- HASH_SEQ_STATUS status;
+ dlist_mutable_iter iter;
LOCALLOCK *locallock;
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
+ {
+ locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
LockReassignOwner(locallock, parent);
+ }
}
else
{
@@ -3133,8 +3137,7 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
void
AtPrepare_Locks(void)
{
- HASH_SEQ_STATUS status;
- LOCALLOCK *locallock;
+ dlist_mutable_iter iter;
/*
* For the most part, we don't need to touch shared memory for this ---
@@ -3142,10 +3145,9 @@ AtPrepare_Locks(void)
* Fast-path locks are an exception, however: we move any such locks to
* the main table before allowing PREPARE TRANSACTION to succeed.
*/
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
{
+ LOCALLOCK *locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
TwoPhaseLockRecord record;
LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
bool haveSessionLock;
@@ -3244,8 +3246,7 @@ void
PostPrepare_Locks(TransactionId xid)
{
PGPROC *newproc = TwoPhaseGetDummyProc(xid);
- HASH_SEQ_STATUS status;
- LOCALLOCK *locallock;
+ dlist_mutable_iter iter;
LOCK *lock;
PROCLOCK *proclock;
PROCLOCKTAG proclocktag;
@@ -3267,10 +3268,9 @@ PostPrepare_Locks(TransactionId xid)
* pointing to the same proclock, and we daren't end up with any dangling
* pointers.
*/
- hash_seq_init(&status, LockMethodLocalHash);
-
- while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
+ dlist_foreach_modify(iter, &MyProc->localLocks)
{
+ LOCALLOCK *locallock = dlist_container(LOCALLOCK, procLink, iter.cur);
LOCALLOCKOWNER *lockOwners = locallock->lockOwners;
bool haveSessionLock;
bool haveXactLock;
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 89c80fb..a22d73a 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -389,6 +389,7 @@ InitProcess(void)
MyProc->lwWaitMode = 0;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
+ dlist_init(&MyProc->localLocks);
#ifdef USE_ASSERT_CHECKING
{
int i;
@@ -568,6 +569,7 @@ InitAuxiliaryProcess(void)
MyProc->lwWaitMode = 0;
MyProc->waitLock = NULL;
MyProc->waitProcLock = NULL;
+ dlist_init(&MyProc->localLocks);
#ifdef USE_ASSERT_CHECKING
{
int i;
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 16b927c..20887f4 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -18,6 +18,7 @@
#error "lock.h may not be included from frontend code"
#endif
+#include "lib/ilist.h"
#include "storage/lockdefs.h"
#include "storage/backendid.h"
#include "storage/lwlock.h"
@@ -406,6 +407,7 @@ typedef struct LOCALLOCK
/* data */
LOCK *lock; /* associated LOCK object, if any */
PROCLOCK *proclock; /* associated PROCLOCK object, if any */
+ dlist_node procLink; /* list link in PGPROC's list of LOCALLOCKs */
uint32 hashcode; /* copy of LOCKTAG's hash value */
int64 nLocks; /* total number of times lock is held */
bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index d203acb..031e004 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -138,6 +138,7 @@ struct PGPROC
/* waitLock and waitProcLock are NULL if not currently waiting. */
LOCK *waitLock; /* Lock object we're sleeping on ... */
PROCLOCK *waitProcLock; /* Per-holder info for awaited lock */
+ dlist_head localLocks; /* List of LOCALLOCKs */
LOCKMODE waitLockMode; /* type of lock we're waiting for */
LOCKMASK heldLocks; /* bitmask for lock types already held on this
* lock object by this backend */