Make FP_LOCK_SLOTS_PER_BACKEND look like a function
authorTomas Vondra <[email protected]>
Tue, 4 Mar 2025 17:33:09 +0000 (18:33 +0100)
committerTomas Vondra <[email protected]>
Tue, 4 Mar 2025 17:33:12 +0000 (18:33 +0100)
The FP_LOCK_SLOTS_PER_BACKEND macro looks like a constant, but it
depends on the max_locks_per_transaction GUC, and thus can change. This
is non-obvious and confusing, so make it look more like a function by
renaming it to FastPathLockSlotsPerBackend().

While at it, use the macro when initializing fast-path shared memory,
instead of using the formula.

Reported-by: Andres Freund
Discussion: https://postgr.es/m/ffiwtzc6vedo6wb4gbwelon5nefqg675t5c7an2ta7pcz646cg%40qwmkdb3l4ett

src/backend/storage/lmgr/lock.c
src/backend/storage/lmgr/proc.c
src/backend/utils/init/postinit.c
src/include/storage/proc.h

index 11b4d1085bb417011567a20f5b19c45980222e49..ccfe6b69bf523b5e32b2cb0a874a4713d5a0a8f9 100644 (file)
@@ -226,10 +226,10 @@ int           FastPathLockGroupsPerBackend = 0;
  * the FAST_PATH_SLOT macro, split it into group and index (in the group).
  */
 #define FAST_PATH_GROUP(index) \
-   (AssertMacro((uint32) (index) < FP_LOCK_SLOTS_PER_BACKEND), \
+   (AssertMacro((uint32) (index) < FastPathLockSlotsPerBackend()), \
     ((index) / FP_LOCK_SLOTS_PER_GROUP))
 #define FAST_PATH_INDEX(index) \
-   (AssertMacro((uint32) (index) < FP_LOCK_SLOTS_PER_BACKEND), \
+   (AssertMacro((uint32) (index) < FastPathLockSlotsPerBackend()), \
     ((index) % FP_LOCK_SLOTS_PER_GROUP))
 
 /* Macros for manipulating proc->fpLockBits */
@@ -242,7 +242,7 @@ int         FastPathLockGroupsPerBackend = 0;
 #define FAST_PATH_BIT_POSITION(n, l) \
    (AssertMacro((l) >= FAST_PATH_LOCKNUMBER_OFFSET), \
     AssertMacro((l) < FAST_PATH_BITS_PER_SLOT+FAST_PATH_LOCKNUMBER_OFFSET), \
-    AssertMacro((n) < FP_LOCK_SLOTS_PER_BACKEND), \
+    AssertMacro((n) < FastPathLockSlotsPerBackend()), \
     ((l) - FAST_PATH_LOCKNUMBER_OFFSET + FAST_PATH_BITS_PER_SLOT * (FAST_PATH_INDEX(n))))
 #define FAST_PATH_SET_LOCKMODE(proc, n, l) \
     FAST_PATH_BITS(proc, n) |= UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l)
@@ -2691,7 +2691,7 @@ static bool
 FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode)
 {
    uint32      i;
-   uint32      unused_slot = FP_LOCK_SLOTS_PER_BACKEND;
+   uint32      unused_slot = FastPathLockSlotsPerBackend();
 
    /* fast-path group the lock belongs to */
    uint32      group = FAST_PATH_REL_GROUP(relid);
@@ -2713,7 +2713,7 @@ FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode)
    }
 
    /* If no existing entry, use any empty slot. */
-   if (unused_slot < FP_LOCK_SLOTS_PER_BACKEND)
+   if (unused_slot < FastPathLockSlotsPerBackend())
    {
        MyProc->fpRelId[unused_slot] = relid;
        FAST_PATH_SET_LOCKMODE(MyProc, unused_slot, lockmode);
index 49204f91a20159248eff14e3e9a3d5e28465850e..749a79d48ef9ed62e92224b8d3d9a98349919e1a 100644 (file)
@@ -116,7 +116,7 @@ ProcGlobalShmemSize(void)
     * nicely aligned in each backend.
     */
    fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
-   fpRelIdSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(Oid) * FP_LOCK_SLOTS_PER_GROUP);
+   fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
 
    size = add_size(size, mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
 
@@ -231,7 +231,7 @@ InitProcGlobal(void)
     * shared memory and then divide that between backends.
     */
    fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
-   fpRelIdSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(Oid) * FP_LOCK_SLOTS_PER_GROUP);
+   fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
 
    fpPtr = ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize));
    MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize));
index b428a59bdd26b4bf23d6d06f772c2a02f9deba65..ee1a9d5d98bbbf8a0cceee0f52962441804d3a0a 100644 (file)
@@ -587,7 +587,7 @@ InitializeFastPathLocks(void)
    while (FastPathLockGroupsPerBackend < FP_LOCK_GROUPS_PER_BACKEND_MAX)
    {
        /* stop once we exceed max_locks_per_xact */
-       if (FastPathLockGroupsPerBackend * FP_LOCK_SLOTS_PER_GROUP >= max_locks_per_xact)
+       if (FastPathLockSlotsPerBackend() >= max_locks_per_xact)
            break;
 
        FastPathLockGroupsPerBackend *= 2;
index 20777f7d5ae13ff7d4e5354ce2d173a8722a6b20..114eb1f8f76040394d5194cb3d4e768be4cb604f 100644 (file)
@@ -88,7 +88,8 @@ extern PGDLLIMPORT int FastPathLockGroupsPerBackend;
 
 #define        FP_LOCK_GROUPS_PER_BACKEND_MAX  1024
 #define        FP_LOCK_SLOTS_PER_GROUP     16  /* don't change */
-#define        FP_LOCK_SLOTS_PER_BACKEND   (FP_LOCK_SLOTS_PER_GROUP * FastPathLockGroupsPerBackend)
+#define        FastPathLockSlotsPerBackend() \
+   (FP_LOCK_SLOTS_PER_GROUP * FastPathLockGroupsPerBackend)
 
 /*
  * Flags for PGPROC.delayChkptFlags