=== Applying patches on top of PostgreSQL commit ID 66ad764c8d517f59577d41ac3dad786729c9e10e === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Tue Apr 14 20:09:27 UTC 2026 On branch cf/6358 nothing to commit, working tree clean === using 'git am' to apply patch ./v1-0001-Replace-PROCLOCK-hash-table-with-partitioned-free.patch === Applying: Replace PROCLOCK hash table with partitioned free list allocator Using index info to reconstruct a base tree... M src/backend/storage/lmgr/lock.c M src/include/storage/lock.h Falling back to patching base and 3-way merge... Auto-merging src/include/storage/lock.h Auto-merging src/backend/storage/lmgr/lock.c CONFLICT (content): Merge conflict in src/backend/storage/lmgr/lock.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Replace PROCLOCK hash table with partitioned free list allocator When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./v1-0001-Replace-PROCLOCK-hash-table-with-partitioned-free.patch === patching file src/backend/storage/lmgr/README patching file src/backend/storage/lmgr/lock.c Hunk #1 succeeded at 324 (offset 11 lines). Hunk #2 succeeded at 422 (offset 11 lines). Hunk #3 FAILED at 437. Hunk #4 FAILED at 474. Hunk #5 succeeded at 560 (offset -2 lines). Hunk #6 succeeded at 1115 (offset 9 lines). Hunk #7 succeeded at 1266 (offset 9 lines). Hunk #8 succeeded at 1303 (offset 9 lines). Hunk #9 succeeded at 1734 (offset 9 lines). Hunk #10 succeeded at 2224 (offset 9 lines). Hunk #11 succeeded at 2234 (offset 9 lines). Hunk #12 succeeded at 3007 (offset 9 lines). Hunk #13 succeeded at 3019 (offset 9 lines). Hunk #14 succeeded at 3281 (offset 9 lines). Hunk #15 succeeded at 3304 (offset 9 lines). Hunk #16 succeeded at 3574 (offset 9 lines). Hunk #17 succeeded at 3691 (offset 9 lines). Hunk #18 FAILED at 3732. Hunk #19 succeeded at 3747 (offset -16 lines). Hunk #20 succeeded at 3875 (offset -16 lines). Hunk #21 succeeded at 4138 (offset -17 lines). Hunk #22 succeeded at 4152 (offset -17 lines). Hunk #23 succeeded at 4173 (offset -17 lines). Hunk #24 succeeded at 4285 (offset -17 lines). Hunk #25 succeeded at 4342 (offset -17 lines). Hunk #26 succeeded at 4404 (offset -17 lines). 3 out of 26 hunks FAILED -- saving rejects to file src/backend/storage/lmgr/lock.c.rej patching file src/include/storage/lock.h Hunk #1 succeeded at 162 (offset -171 lines). Unstaged changes after reset: M src/backend/storage/lmgr/README M src/backend/storage/lmgr/lock.c M src/include/storage/lock.h Removing src/backend/storage/lmgr/lock.c.rej === using 'git apply' to apply patch ./v1-0001-Replace-PROCLOCK-hash-table-with-partitioned-free.patch === Applied patch to 'src/backend/storage/lmgr/README' cleanly. Applied patch to 'src/backend/storage/lmgr/lock.c' with conflicts. Applied patch to 'src/include/storage/lock.h' cleanly. U src/backend/storage/lmgr/lock.c diff --cc src/backend/storage/lmgr/lock.c index c221fe96889,bfdfa9c9a72..00000000000 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@@ -314,23 -311,19 +314,27 @@@ typedef struc static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static void LockManagerShmemRequest(void *arg); +static void LockManagerShmemInit(void *arg); + +const ShmemCallbacks LockManagerShmemCallbacks = { + .request_fn = LockManagerShmemRequest, + .init_fn = LockManagerShmemInit, +}; + /* - * Pointers to hash tables containing lock state + * Pointers to shared lock state * - * The LockMethodLockHash and LockMethodProcLockHash hash tables are in - * shared memory; LockMethodLocalHash is local to each backend. + * LockMethodLockHash is a hash table for LOCK objects. ProcLockArray is + * an array of all PROCLOCK objects, managed via partitioned free lists in + * ProcLockFreeList. These are all in shared memory; LockMethodLocalHash + * is local to each backend. */ static HTAB *LockMethodLockHash; - static HTAB *LockMethodProcLockHash; + static PROCLOCK *ProcLockArray; /* array of all PROCLOCK structs */ + static dlist_head *ProcLockFreeList; /* partitioned free lists */ + static int MaxProcLocks; /* size of ProcLockArray */ static HTAB *LockMethodLocalHash; @@@ -442,58 -434,89 +445,104 @@@ static void GetSingleProcBlockerStatusD /* - * Initialize the lock manager's shmem data structures. + * Register the lock manager's shmem data structures. * ++<<<<<<< ours + * In addition to this, each backend must also call InitLockManagerAccess() to + * create the locallock hash table. ++======= + * This is called from CreateSharedMemoryAndSemaphores(), which see for more + * comments. In the normal postmaster case, the shared hash table for LOCKs + * and the PROCLOCK array/freelists are created here, and backends inherit + * pointers to them via fork(). In the EXEC_BACKEND case, each backend + * re-executes this code to obtain pointers to the already existing shared + * structures. In either case, each backend must also call + * InitLockManagerAccess() to create the locallock hash table. ++>>>>>>> theirs */ -void -LockManagerShmemInit(void) +static void +LockManagerShmemRequest(void *arg) { - HASHCTL info; - int64 init_table_size, - max_table_size; - bool found; + int64 max_table_size; /* - * Compute init/max size to request for lock hashtables. Note these - * calculations must agree with LockManagerShmemSize! + * Compute sizes for lock hashtables. Note that these calculations must + * agree with LockManagerShmemSize! */ max_table_size = NLOCKENTS(); - init_table_size = max_table_size / 2; /* - * Allocate hash table for LOCK structs. This stores per-locked-object + * Hash table for LOCK structs. This stores per-locked-object * information. */ - info.keysize = sizeof(LOCKTAG); - info.entrysize = sizeof(LOCK); - info.num_partitions = NUM_LOCK_PARTITIONS; - - LockMethodLockHash = ShmemInitHash("LOCK hash", - init_table_size, - max_table_size, - &info, - HASH_ELEM | HASH_BLOBS | HASH_PARTITION); + ShmemRequestHash(.name = "LOCK hash", + .nelems = max_table_size, + .ptr = &LockMethodLockHash, + .hash_info.keysize = sizeof(LOCKTAG), + .hash_info.entrysize = sizeof(LOCK), + .hash_info.num_partitions = NUM_LOCK_PARTITIONS, + .hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION, + ); /* Assume an average of 2 holders per lock */ max_table_size *= 2; ++<<<<<<< ours + + ShmemRequestHash(.name = "PROCLOCK hash", + .nelems = max_table_size, + .ptr = &LockMethodProcLockHash, + .hash_info.keysize = sizeof(PROCLOCKTAG), + .hash_info.entrysize = sizeof(PROCLOCK), + .hash_info.hash = proclock_hash, + .hash_info.num_partitions = NUM_LOCK_PARTITIONS, + .hash_flags = HASH_ELEM | HASH_FUNCTION | HASH_PARTITION, + ); + + ShmemRequestStruct(.name = "Fast Path Strong Relation Lock Data", + .size = sizeof(FastPathStrongRelationLockData), + .ptr = (void **) (void *) &FastPathStrongRelationLocks, + ); +} ++======= + + /* + * Allocate array for PROCLOCK structs. This stores + * per-lock-per-holder information. + */ + MaxProcLocks = max_table_size; + ProcLockArray = (PROCLOCK *) + ShmemInitStruct("PROCLOCK array", + mul_size(MaxProcLocks, sizeof(PROCLOCK)), + &found); + + ProcLockFreeList = (dlist_head *) + ShmemInitStruct("PROCLOCK free lists", + mul_size(NUM_LOCK_PARTITIONS, sizeof(dlist_head)), + &found); + + if (!found) + { + int i; + + /* Initialize partitioned free lists */ + for (i = 0; i < NUM_LOCK_PARTITIONS; i++) + dlist_init(&ProcLockFreeList[i]); + + /* Link all PROCLOCK entries into the free lists */ + for (i = 0; i < MaxProcLocks; i++) + { + int partition = i % NUM_LOCK_PARTITIONS; + + dlist_push_tail(&ProcLockFreeList[partition], + &ProcLockArray[i].lockLink); + } + } ++>>>>>>> theirs - /* - * Allocate fast-path structures. - */ - FastPathStrongRelationLocks = - ShmemInitStruct("Fast Path Strong Relation Lock Data", - sizeof(FastPathStrongRelationLockData), &found); - if (!found) - SpinLockInit(&FastPathStrongRelationLocks->mutex); +static void +LockManagerShmemInit(void *arg) +{ + SpinLockInit(&FastPathStrongRelationLocks->mutex); } /* @@@ -3759,6 -3738,32 +3775,35 @@@ PostPrepare_Locks(FullTransactionId fxi /* ++<<<<<<< ours ++======= + * Estimate shared-memory space used for lock tables + */ + Size + LockManagerShmemSize(void) + { + Size size = 0; + long max_table_size; + + /* lock hash table */ + max_table_size = NLOCKENTS(); + size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK))); + + /* proclock array and free lists */ + max_table_size *= 2; + size = add_size(size, mul_size(max_table_size, sizeof(PROCLOCK))); + size = add_size(size, mul_size(NUM_LOCK_PARTITIONS, sizeof(dlist_head))); + + /* + * Since NLOCKENTS is only an estimate, add 10% safety margin. + */ + size = add_size(size, size / 10); + + return size; + } + + /* ++>>>>>>> theirs * GetLockStatusData - Return a summary of the lock manager's internal * status, for use in a user-level reporting function. *