Commit 8e5ac74c authored by Robert Haas's avatar Robert Haas

Some refinement for the "fast path" lock patch.

1. In GetLockStatusData, avoid initializing instance before we've ensured
that the array is large enough.  Otherwise, if repalloc moves the block
around, we're hosed.

2. Add the word "Relation" to the name of some identifiers, to avoid
assuming that the fast-path mechanism will only ever apply to relations
(though these particular parts certainly will).  Some of the macros
could possibly use similar treatment, but the names are getting awfully
long already.

3. Add a missing word to comment in AtPrepare_Locks().
parent cdd61237
...@@ -155,11 +155,11 @@ static int FastPathLocalUseCount = 0; ...@@ -155,11 +155,11 @@ static int FastPathLocalUseCount = 0;
#define FastPathStrongMode(mode) ((mode) > ShareUpdateExclusiveLock) #define FastPathStrongMode(mode) ((mode) > ShareUpdateExclusiveLock)
#define FastPathRelevantMode(mode) ((mode) != ShareUpdateExclusiveLock) #define FastPathRelevantMode(mode) ((mode) != ShareUpdateExclusiveLock)
static bool FastPathGrantLock(Oid relid, LOCKMODE lockmode); static bool FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode);
static bool FastPathUnGrantLock(Oid relid, LOCKMODE lockmode); static bool FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode);
static bool FastPathTransferLocks(LockMethod lockMethodTable, static bool FastPathTransferRelationLocks(LockMethod lockMethodTable,
const LOCKTAG *locktag, uint32 hashcode); const LOCKTAG *locktag, uint32 hashcode);
static PROCLOCK *FastPathGetLockEntry(LOCALLOCK *locallock); static PROCLOCK *FastPathGetRelationLockEntry(LOCALLOCK *locallock);
/* /*
* To make the fast-path lock mechanism work, we must have some way of * To make the fast-path lock mechanism work, we must have some way of
...@@ -186,9 +186,9 @@ typedef struct ...@@ -186,9 +186,9 @@ typedef struct
{ {
slock_t mutex; slock_t mutex;
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]; uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongLockData; } FastPathStrongRelationLockData;
FastPathStrongLockData *FastPathStrongLocks; FastPathStrongRelationLockData *FastPathStrongRelationLocks;
#ifndef LOCK_DEBUG #ifndef LOCK_DEBUG
static bool Dummy_trace = false; static bool Dummy_trace = false;
...@@ -415,10 +415,11 @@ InitLocks(void) ...@@ -415,10 +415,11 @@ InitLocks(void)
/* /*
* Allocate fast-path structures. * Allocate fast-path structures.
*/ */
FastPathStrongLocks = ShmemInitStruct("Fast Path Strong Lock Data", FastPathStrongRelationLocks =
sizeof(FastPathStrongLockData), &found); ShmemInitStruct("Fast Path Strong Relation Lock Data",
sizeof(FastPathStrongRelationLockData), &found);
if (!found) if (!found)
SpinLockInit(&FastPathStrongLocks->mutex); SpinLockInit(&FastPathStrongRelationLocks->mutex);
/* /*
* Allocate non-shared hash table for LOCALLOCK structs. This stores lock * Allocate non-shared hash table for LOCALLOCK structs. This stores lock
...@@ -720,10 +721,11 @@ LockAcquireExtended(const LOCKTAG *locktag, ...@@ -720,10 +721,11 @@ LockAcquireExtended(const LOCKTAG *locktag,
* yet to begin to transfer fast-path locks. * yet to begin to transfer fast-path locks.
*/ */
LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE); LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE);
if (FastPathStrongLocks->count[fasthashcode] != 0) if (FastPathStrongRelationLocks->count[fasthashcode] != 0)
acquired = false; acquired = false;
else else
acquired = FastPathGrantLock(locktag->locktag_field2, lockmode); acquired = FastPathGrantRelationLock(locktag->locktag_field2,
lockmode);
LWLockRelease(MyProc->backendLock); LWLockRelease(MyProc->backendLock);
if (acquired) if (acquired)
{ {
...@@ -742,11 +744,12 @@ LockAcquireExtended(const LOCKTAG *locktag, ...@@ -742,11 +744,12 @@ LockAcquireExtended(const LOCKTAG *locktag,
* instruction here, on architectures where that is supported. * instruction here, on architectures where that is supported.
*/ */
Assert(locallock->holdsStrongLockCount == FALSE); Assert(locallock->holdsStrongLockCount == FALSE);
SpinLockAcquire(&FastPathStrongLocks->mutex); SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
FastPathStrongLocks->count[fasthashcode]++; FastPathStrongRelationLocks->count[fasthashcode]++;
locallock->holdsStrongLockCount = TRUE; locallock->holdsStrongLockCount = TRUE;
SpinLockRelease(&FastPathStrongLocks->mutex); SpinLockRelease(&FastPathStrongRelationLocks->mutex);
if (!FastPathTransferLocks(lockMethodTable, locktag, hashcode)) if (!FastPathTransferRelationLocks(lockMethodTable, locktag,
hashcode))
{ {
if (reportMemoryError) if (reportMemoryError)
ereport(ERROR, ereport(ERROR,
...@@ -1099,11 +1102,11 @@ RemoveLocalLock(LOCALLOCK *locallock) ...@@ -1099,11 +1102,11 @@ RemoveLocalLock(LOCALLOCK *locallock)
uint32 fasthashcode; uint32 fasthashcode;
fasthashcode = FastPathStrongLockHashPartition(locallock->hashcode); fasthashcode = FastPathStrongLockHashPartition(locallock->hashcode);
SpinLockAcquire(&FastPathStrongLocks->mutex); SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
Assert(FastPathStrongLocks->count[fasthashcode] > 0); Assert(FastPathStrongRelationLocks->count[fasthashcode] > 0);
FastPathStrongLocks->count[fasthashcode]--; FastPathStrongRelationLocks->count[fasthashcode]--;
locallock->holdsStrongLockCount = FALSE; locallock->holdsStrongLockCount = FALSE;
SpinLockRelease(&FastPathStrongLocks->mutex); SpinLockRelease(&FastPathStrongRelationLocks->mutex);
} }
if (!hash_search(LockMethodLocalHash, if (!hash_search(LockMethodLocalHash,
(void *) &(locallock->tag), (void *) &(locallock->tag),
...@@ -1642,7 +1645,8 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock) ...@@ -1642,7 +1645,8 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
* it here. Another backend may have moved it to the main table. * it here. Another backend may have moved it to the main table.
*/ */
LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE); LWLockAcquire(MyProc->backendLock, LW_EXCLUSIVE);
released = FastPathUnGrantLock(locktag->locktag_field2, lockmode); released = FastPathUnGrantRelationLock(locktag->locktag_field2,
lockmode);
LWLockRelease(MyProc->backendLock); LWLockRelease(MyProc->backendLock);
if (released) if (released)
{ {
...@@ -1825,7 +1829,7 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks) ...@@ -1825,7 +1829,7 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
/* Attempt fast-path release. */ /* Attempt fast-path release. */
relid = locallock->tag.lock.locktag_field2; relid = locallock->tag.lock.locktag_field2;
if (FastPathUnGrantLock(relid, lockmode)) if (FastPathUnGrantRelationLock(relid, lockmode))
{ {
RemoveLocalLock(locallock); RemoveLocalLock(locallock);
continue; continue;
...@@ -2117,11 +2121,11 @@ LockReassignCurrentOwner(void) ...@@ -2117,11 +2121,11 @@ LockReassignCurrentOwner(void)
} }
/* /*
* FastPathGrantLock * FastPathGrantRelationLock
* Grant lock using per-backend fast-path array, if there is space. * Grant lock using per-backend fast-path array, if there is space.
*/ */
static bool static bool
FastPathGrantLock(Oid relid, LOCKMODE lockmode) FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode)
{ {
uint32 f; uint32 f;
uint32 unused_slot = FP_LOCK_SLOTS_PER_BACKEND; uint32 unused_slot = FP_LOCK_SLOTS_PER_BACKEND;
...@@ -2153,12 +2157,12 @@ FastPathGrantLock(Oid relid, LOCKMODE lockmode) ...@@ -2153,12 +2157,12 @@ FastPathGrantLock(Oid relid, LOCKMODE lockmode)
} }
/* /*
* FastPathUnGrantLock * FastPathUnGrantRelationLock
* Release fast-path lock, if present. Update backend-private local * Release fast-path lock, if present. Update backend-private local
* use count, while we're at it. * use count, while we're at it.
*/ */
static bool static bool
FastPathUnGrantLock(Oid relid, LOCKMODE lockmode) FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode)
{ {
uint32 f; uint32 f;
bool result = false; bool result = false;
...@@ -2180,12 +2184,12 @@ FastPathUnGrantLock(Oid relid, LOCKMODE lockmode) ...@@ -2180,12 +2184,12 @@ FastPathUnGrantLock(Oid relid, LOCKMODE lockmode)
} }
/* /*
* FastPathTransferLocks * FastPathTransferRelationLocks
* Transfer locks matching the given lock tag from per-backend fast-path * Transfer locks matching the given lock tag from per-backend fast-path
* arrays to the shared hash table. * arrays to the shared hash table.
*/ */
static bool static bool
FastPathTransferLocks(LockMethod lockMethodTable, const LOCKTAG *locktag, FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag,
uint32 hashcode) uint32 hashcode)
{ {
LWLockId partitionLock = LockHashPartitionLock(hashcode); LWLockId partitionLock = LockHashPartitionLock(hashcode);
...@@ -2267,7 +2271,7 @@ FastPathTransferLocks(LockMethod lockMethodTable, const LOCKTAG *locktag, ...@@ -2267,7 +2271,7 @@ FastPathTransferLocks(LockMethod lockMethodTable, const LOCKTAG *locktag,
* transferring it to the primary lock table if necessary. * transferring it to the primary lock table if necessary.
*/ */
static PROCLOCK * static PROCLOCK *
FastPathGetLockEntry(LOCALLOCK *locallock) FastPathGetRelationLockEntry(LOCALLOCK *locallock)
{ {
LockMethod lockMethodTable = LockMethods[DEFAULT_LOCKMETHOD]; LockMethod lockMethodTable = LockMethods[DEFAULT_LOCKMETHOD];
LOCKTAG *locktag = &locallock->tag.lock; LOCKTAG *locktag = &locallock->tag.lock;
...@@ -2650,9 +2654,9 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc, ...@@ -2650,9 +2654,9 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
&& FastPathTag(&lock->tag) && FastPathStrongMode(lockmode)) && FastPathTag(&lock->tag) && FastPathStrongMode(lockmode))
{ {
uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode); uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode);
SpinLockAcquire(&FastPathStrongLocks->mutex); SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
FastPathStrongLocks->count[fasthashcode]--; FastPathStrongRelationLocks->count[fasthashcode]--;
SpinLockRelease(&FastPathStrongLocks->mutex); SpinLockRelease(&FastPathStrongRelationLocks->mutex);
} }
} }
...@@ -2715,11 +2719,11 @@ AtPrepare_Locks(void) ...@@ -2715,11 +2719,11 @@ AtPrepare_Locks(void)
/* /*
* If the local lock was taken via the fast-path, we need to move it * If the local lock was taken via the fast-path, we need to move it
* to the primary lock table, or just get a pointer to the existing * to the primary lock table, or just get a pointer to the existing
* primary lock table if by chance it's already been transferred. * primary lock table entry if by chance it's already been transferred.
*/ */
if (locallock->proclock == NULL) if (locallock->proclock == NULL)
{ {
locallock->proclock = FastPathGetLockEntry(locallock); locallock->proclock = FastPathGetRelationLockEntry(locallock);
locallock->lock = locallock->proclock->tag.myLock; locallock->lock = locallock->proclock->tag.myLock;
} }
...@@ -3010,7 +3014,7 @@ GetLockStatusData(void) ...@@ -3010,7 +3014,7 @@ GetLockStatusData(void)
for (f = 0; f < FP_LOCK_SLOTS_PER_BACKEND; ++f) for (f = 0; f < FP_LOCK_SLOTS_PER_BACKEND; ++f)
{ {
LockInstanceData *instance = &data->locks[el]; LockInstanceData *instance;
uint32 lockbits = FAST_PATH_GET_BITS(proc, f); uint32 lockbits = FAST_PATH_GET_BITS(proc, f);
/* Skip unallocated slots. */ /* Skip unallocated slots. */
...@@ -3024,6 +3028,7 @@ GetLockStatusData(void) ...@@ -3024,6 +3028,7 @@ GetLockStatusData(void)
repalloc(data->locks, sizeof(LockInstanceData) * els); repalloc(data->locks, sizeof(LockInstanceData) * els);
} }
instance = &data->locks[el];
SET_LOCKTAG_RELATION(instance->locktag, proc->databaseId, SET_LOCKTAG_RELATION(instance->locktag, proc->databaseId,
proc->fpRelId[f]); proc->fpRelId[f]);
instance->holdMask = lockbits << FAST_PATH_LOCKNUMBER_OFFSET; instance->holdMask = lockbits << FAST_PATH_LOCKNUMBER_OFFSET;
...@@ -3455,9 +3460,9 @@ lock_twophase_recover(TransactionId xid, uint16 info, ...@@ -3455,9 +3460,9 @@ lock_twophase_recover(TransactionId xid, uint16 info,
if (FastPathTag(&lock->tag) && FastPathStrongMode(lockmode)) if (FastPathTag(&lock->tag) && FastPathStrongMode(lockmode))
{ {
uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode); uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode);
SpinLockAcquire(&FastPathStrongLocks->mutex); SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
FastPathStrongLocks->count[fasthashcode]++; FastPathStrongRelationLocks->count[fasthashcode]++;
SpinLockRelease(&FastPathStrongLocks->mutex); SpinLockRelease(&FastPathStrongRelationLocks->mutex);
} }
LWLockRelease(partitionLock); LWLockRelease(partitionLock);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment