1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Convert FastPathStrongRelationLocks to atomics.

Currently, the lock counts are unsigned integers protected by a
spinlock.  By converting them to atomic variables, we can remove
the spinlock and the FastPathStrongRelationLockData wrapper struct.

Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Tested-by: solai v <solai.cdac@gmail.com>
Discussion: https://postgr.es/m/alAJeRRzehDjLaF1%40nathan
This commit is contained in:
Nathan Bossart
2026-09-04 13:02:22 -05:00
parent 7344937cbe
commit 74c77052bc
2 changed files with 17 additions and 41 deletions

View File

@@ -40,11 +40,11 @@
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/shmem.h"
#include "storage/spin.h"
#include "storage/standby.h"
#include "storage/subsystems.h"
#include "utils/memutils.h"
@@ -306,13 +306,7 @@ static PROCLOCK *FastPathGetRelationLockEntry(LOCALLOCK *locallock);
#define FastPathStrongLockHashPartition(hashcode) \
((hashcode) % FAST_PATH_STRONG_LOCK_HASH_PARTITIONS)
typedef struct
{
slock_t mutex;
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static pg_atomic_uint32 *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
@@ -484,7 +478,8 @@ LockManagerShmemRequest(void *arg)
);
ShmemRequestStruct(.name = "Fast Path Strong Relation Lock Data",
.size = sizeof(FastPathStrongRelationLockData),
.size = mul_size(sizeof(pg_atomic_uint32),
FAST_PATH_STRONG_LOCK_HASH_PARTITIONS),
.ptr = (void **) (void *) &FastPathStrongRelationLocks,
);
}
@@ -492,7 +487,8 @@ LockManagerShmemRequest(void *arg)
static void
LockManagerShmemInit(void *arg)
{
SpinLockInit(&FastPathStrongRelationLocks->mutex);
for (int i = 0; i < FAST_PATH_STRONG_LOCK_HASH_PARTITIONS; i++)
pg_atomic_init_u32(&FastPathStrongRelationLocks[i], 0);
}
/*
@@ -1002,11 +998,11 @@ LockAcquireExtended(const LOCKTAG *locktag,
/*
* LWLockAcquire acts as a memory sequencing point, so it's safe
* to assume that any strong locker whose increment to
* FastPathStrongRelationLocks->counts becomes visible after we
* test it has yet to begin to transfer fast-path locks.
* FastPathStrongRelationLocks becomes visible after we test it
* has yet to begin to transfer fast-path locks.
*/
LWLockAcquire(&MyProc->fpInfoLock, LW_EXCLUSIVE);
if (FastPathStrongRelationLocks->count[fasthashcode] != 0)
if (pg_atomic_read_u32(&FastPathStrongRelationLocks[fasthashcode]) != 0)
acquired = false;
else
acquired = FastPathGrantRelationLock(locktag->locktag_field2,
@@ -1511,11 +1507,9 @@ RemoveLocalLock(LOCALLOCK *locallock)
fasthashcode = FastPathStrongLockHashPartition(locallock->hashcode);
SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
Assert(FastPathStrongRelationLocks->count[fasthashcode] > 0);
FastPathStrongRelationLocks->count[fasthashcode]--;
Assert(pg_atomic_read_u32(&FastPathStrongRelationLocks[fasthashcode]) > 0);
pg_atomic_fetch_sub_u32(&FastPathStrongRelationLocks[fasthashcode], 1);
locallock->holdsStrongLockCount = false;
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
}
if (!hash_search(LockMethodLocalHash,
@@ -1844,20 +1838,9 @@ BeginStrongLockAcquire(LOCALLOCK *locallock, uint32 fasthashcode)
Assert(StrongLockInProgress == NULL);
Assert(locallock->holdsStrongLockCount == false);
/*
* Adding to a memory location is not atomic, so we take a spinlock to
* ensure we don't collide with someone else trying to bump the count at
* the same time.
*
* XXX: It might be worth considering using an atomic fetch-and-add
* instruction here, on architectures where that is supported.
*/
SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
FastPathStrongRelationLocks->count[fasthashcode]++;
pg_atomic_fetch_add_u32(&FastPathStrongRelationLocks[fasthashcode], 1);
locallock->holdsStrongLockCount = true;
StrongLockInProgress = locallock;
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
}
/*
@@ -1885,12 +1868,10 @@ AbortStrongLockAcquire(void)
fasthashcode = FastPathStrongLockHashPartition(locallock->hashcode);
Assert(locallock->holdsStrongLockCount == true);
SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
Assert(FastPathStrongRelationLocks->count[fasthashcode] > 0);
FastPathStrongRelationLocks->count[fasthashcode]--;
Assert(pg_atomic_read_u32(&FastPathStrongRelationLocks[fasthashcode]) > 0);
pg_atomic_fetch_sub_u32(&FastPathStrongRelationLocks[fasthashcode], 1);
locallock->holdsStrongLockCount = false;
StrongLockInProgress = NULL;
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
}
/*
@@ -3374,10 +3355,8 @@ LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc,
{
uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode);
SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
Assert(FastPathStrongRelationLocks->count[fasthashcode] > 0);
FastPathStrongRelationLocks->count[fasthashcode]--;
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
Assert(pg_atomic_read_u32(&FastPathStrongRelationLocks[fasthashcode]) > 0);
pg_atomic_fetch_sub_u32(&FastPathStrongRelationLocks[fasthashcode], 1);
}
}
@@ -4507,9 +4486,7 @@ lock_twophase_recover(FullTransactionId fxid, uint16 info,
{
uint32 fasthashcode = FastPathStrongLockHashPartition(hashcode);
SpinLockAcquire(&FastPathStrongRelationLocks->mutex);
FastPathStrongRelationLocks->count[fasthashcode]++;
SpinLockRelease(&FastPathStrongRelationLocks->mutex);
pg_atomic_fetch_add_u32(&FastPathStrongRelationLocks[fasthashcode], 1);
}
LWLockRelease(partitionLock);

View File

@@ -845,7 +845,6 @@ FSMPageData
FakeRelCacheEntry
FakeRelCacheEntryData
FastPathMeta
FastPathStrongRelationLockData
FdwInfo
FdwRoutine
FetchDirection