57 mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts)) 114 "ShareUpdateExclusiveLock",
116 "ShareRowExclusiveLock",
118 "AccessExclusiveLock" 201 #define FAST_PATH_BITS_PER_SLOT 3 202 #define FAST_PATH_LOCKNUMBER_OFFSET 1 203 #define FAST_PATH_MASK ((1 << FAST_PATH_BITS_PER_SLOT) - 1) 204 #define FAST_PATH_GET_BITS(proc, n) \ 205 (((proc)->fpLockBits >> (FAST_PATH_BITS_PER_SLOT * n)) & FAST_PATH_MASK) 206 #define FAST_PATH_BIT_POSITION(n, l) \ 207 (AssertMacro((l) >= FAST_PATH_LOCKNUMBER_OFFSET), \ 208 AssertMacro((l) < FAST_PATH_BITS_PER_SLOT+FAST_PATH_LOCKNUMBER_OFFSET), \ 209 AssertMacro((n) < FP_LOCK_SLOTS_PER_BACKEND), \ 210 ((l) - FAST_PATH_LOCKNUMBER_OFFSET + FAST_PATH_BITS_PER_SLOT * (n))) 211 #define FAST_PATH_SET_LOCKMODE(proc, n, l) \ 212 (proc)->fpLockBits |= UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l) 213 #define FAST_PATH_CLEAR_LOCKMODE(proc, n, l) \ 214 (proc)->fpLockBits &= ~(UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l)) 215 #define FAST_PATH_CHECK_LOCKMODE(proc, n, l) \ 216 ((proc)->fpLockBits & (UINT64CONST(1) << FAST_PATH_BIT_POSITION(n, l))) 226 #define EligibleForRelationFastPath(locktag, mode) \ 227 ((locktag)->locktag_lockmethodid == DEFAULT_LOCKMETHOD && \ 228 (locktag)->locktag_type == LOCKTAG_RELATION && \ 229 (locktag)->locktag_field1 == MyDatabaseId && \ 230 MyDatabaseId != InvalidOid && \ 231 (mode) < ShareUpdateExclusiveLock) 232 #define ConflictsWithRelationFastPath(locktag, mode) \ 233 ((locktag)->locktag_lockmethodid == DEFAULT_LOCKMETHOD && \ 234 (locktag)->locktag_type == LOCKTAG_RELATION && \ 235 (locktag)->locktag_field1 != InvalidOid && \ 236 (mode) > ShareUpdateExclusiveLock) 259 #define FAST_PATH_STRONG_LOCK_HASH_BITS 10 260 #define FAST_PATH_STRONG_LOCK_HASH_PARTITIONS \ 261 (1 << FAST_PATH_STRONG_LOCK_HASH_BITS) 262 #define FastPathStrongLockHashPartition(hashcode) \ 263 ((hashcode) % FAST_PATH_STRONG_LOCK_HASH_PARTITIONS) 311 bool Trace_locks =
false;
312 bool Trace_userlocks =
false;
313 int Trace_lock_table = 0;
314 bool Debug_deadlocks =
false;
318 LOCK_DEBUG_ENABLED(
const LOCKTAG *tag)
323 || (Trace_lock_table &&
331 if (LOCK_DEBUG_ENABLED(&lock->
tag))
333 "%s: lock(%p) id(%u,%u,%u,%u,%u,%u) grantMask(%x) " 334 "req(%d,%d,%d,%d,%d,%d,%d)=%d " 335 "grant(%d,%d,%d,%d,%d,%d,%d)=%d wait(%d) type(%s)",
357 "%s: proclock(%p) lock(%p) method(%u) proc(%p) hold(%x)",
364 #define LOCK_PRINT(where, lock, type) ((void) 0) 365 #define PROCLOCK_PRINT(where, proclockP) ((void) 0) 386 bool decrement_strong_lock_count);
407 long init_table_size,
416 init_table_size = max_table_size / 2;
434 init_table_size *= 2;
454 FastPathStrongRelationLocks =
469 if (LockMethodLocalHash)
475 LockMethodLocalHash =
hash_create(
"LOCALLOCK hash",
491 return LockMethods[lockmethodid];
503 return LockMethods[lockmethodid];
518 return get_hash_value(LockMethodLockHash, (
const void *) locktag);
566 uint32 lockhash = hashcode;
605 MemSet(&localtag, 0,
sizeof(localtag));
613 return (locallock && locallock->
nLocks > 0);
616 #ifdef USE_ASSERT_CHECKING 622 GetLockMethodLocalHash(
void)
642 bool hasWaiters =
false;
644 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
645 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
646 lockMethodTable = LockMethods[lockmethodid];
647 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
648 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
651 if (LOCK_DEBUG_ENABLED(locktag))
652 elog(
LOG,
"LockHasWaiters: lock [%u,%u] %s",
660 MemSet(&localtag, 0,
sizeof(localtag));
671 if (!locallock || locallock->
nLocks <= 0)
690 lock = locallock->
lock;
691 LOCK_PRINT(
"LockHasWaiters: found", lock, lockmode);
774 bool reportMemoryError,
788 bool log_lock =
false;
790 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
791 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
792 lockMethodTable = LockMethods[lockmethodid];
793 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
794 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
801 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
802 errmsg(
"cannot acquire lock mode %s on database objects while recovery is in progress",
804 errhint(
"Only RowExclusiveLock or less can be acquired on database objects during recovery.")));
807 if (LOCK_DEBUG_ENABLED(locktag))
808 elog(
LOG,
"LockAcquire: lock [%u,%u] %s",
822 MemSet(&localtag, 0,
sizeof(localtag));
835 locallock->
lock = NULL;
864 *locallockp = locallock;
872 if (locallock->
nLocks > 0)
886 Assert(!IsRelationExtensionLockHeld);
939 if (FastPathStrongRelationLocks->
count[fasthashcode] != 0)
952 locallock->
lock = NULL;
974 if (locallock->
nLocks == 0)
978 if (reportMemoryError)
980 (
errcode(ERRCODE_OUT_OF_MEMORY),
981 errmsg(
"out of shared memory"),
982 errhint(
"You might need to increase max_locks_per_transaction.")));
1007 hashcode, lockmode);
1012 if (locallock->
nLocks == 0)
1016 if (reportMemoryError)
1018 (
errcode(ERRCODE_OUT_OF_MEMORY),
1019 errmsg(
"out of shared memory"),
1020 errhint(
"You might need to increase max_locks_per_transaction.")));
1026 locallock->
lock = lock;
1034 found_conflict =
true;
1039 if (!found_conflict)
1057 uint32 proclock_hashcode;
1063 (
void *) &(proclock->
tag),
1067 elog(
PANIC,
"proclock table corrupted");
1073 LOCK_PRINT(
"LockAcquire: conditional lock failed", lock, lockmode);
1077 if (locallock->
nLocks == 0)
1123 LOCK_PRINT(
"LockAcquire: INCONSISTENT", lock, lockmode);
1129 LOCK_PRINT(
"LockAcquire: granted", lock, lockmode);
1175 uint32 proclock_hashcode;
1202 LOCK_PRINT(
"LockAcquire: new", lock, lockmode);
1206 LOCK_PRINT(
"LockAcquire: found", lock, lockmode);
1215 proclocktag.
myLock = lock;
1216 proclocktag.
myProc = proc;
1224 (
void *) &proclocktag,
1241 (
void *) &(lock->
tag),
1282 #ifdef CHECK_DEADLOCK_RISK 1305 if (i >= (
int) lockmode)
1307 elog(
LOG,
"deadlock risk: raising lock level" 1308 " from %s to %s on object %u/%u/%u",
1334 elog(
ERROR,
"lock %s on object %u/%u/%u is already held",
1353 #ifdef USE_ASSERT_CHECKING 1355 IsRelationExtensionLockHeld = acquired;
1357 IsPageLockHeld = acquired;
1387 Assert(FastPathStrongRelationLocks->
count[fasthashcode] > 0);
1388 FastPathStrongRelationLocks->
count[fasthashcode]--;
1394 (
void *) &(locallock->
tag),
1428 int totalConflictsRemaining = 0;
1454 for (i = 1; i <= numLockModes; i++)
1458 conflictsRemaining[
i] = 0;
1461 conflictsRemaining[
i] = lock->
granted[
i];
1463 --conflictsRemaining[
i];
1464 totalConflictsRemaining += conflictsRemaining[
i];
1468 if (totalConflictsRemaining == 0)
1470 PROCLOCK_PRINT(
"LockCheckConflicts: resolved (simple)", proclock);
1506 while (otherproclock != NULL)
1508 if (proclock != otherproclock &&
1510 (otherproclock->
holdMask & conflictMask) != 0)
1512 int intersectMask = otherproclock->
holdMask & conflictMask;
1514 for (i = 1; i <= numLockModes; i++)
1518 if (conflictsRemaining[i] <= 0)
1519 elog(
PANIC,
"proclocks held do not match lock");
1520 conflictsRemaining[
i]--;
1521 totalConflictsRemaining--;
1525 if (totalConflictsRemaining == 0)
1538 PROCLOCK_PRINT(
"LockCheckConflicts: conflicting (group)", proclock);
1580 bool wakeupNeeded =
false;
1594 if (lock->
granted[lockmode] == 0)
1600 LOCK_PRINT(
"UnGrantLock: updated", lock, lockmode);
1612 wakeupNeeded =
true;
1620 return wakeupNeeded;
1644 uint32 proclock_hashcode;
1651 (
void *) &(proclock->
tag),
1655 elog(
PANIC,
"proclock table corrupted");
1664 LOCK_PRINT(
"CleanUpLock: deleting", lock, 0);
1667 (
void *) &(lock->
tag),
1673 else if (wakeupNeeded)
1699 if (lockOwners[i].owner == owner)
1705 lockOwners[
i].
owner = owner;
1722 Assert(StrongLockInProgress == NULL);
1735 FastPathStrongRelationLocks->
count[fasthashcode]++;
1737 StrongLockInProgress = locallock;
1748 StrongLockInProgress = NULL;
1761 if (locallock == NULL)
1767 Assert(FastPathStrongRelationLocks->
count[fasthashcode] > 0);
1768 FastPathStrongRelationLocks->
count[fasthashcode]--;
1770 StrongLockInProgress = NULL;
1816 LockMethod lockMethodTable = LockMethods[lockmethodid];
1817 char *
volatile new_status = NULL;
1825 const char *old_status;
1829 new_status = (
char *)
palloc(len + 8 + 1);
1830 memcpy(new_status, old_status, len);
1831 strcpy(new_status + len,
" waiting");
1833 new_status[len] =
'\0';
1836 awaitedLock = locallock;
1837 awaitedOwner = owner;
1929 Assert(0 < lockmethodid && lockmethodid <
lengthof(LockMethods));
1958 LockMethods[lockmethodid], hashcode,
1985 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
1986 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
1987 lockMethodTable = LockMethods[lockmethodid];
1988 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
1989 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
1992 if (LOCK_DEBUG_ENABLED(locktag))
1993 elog(
LOG,
"LockRelease: lock [%u,%u] %s",
2001 MemSet(&localtag, 0,
sizeof(localtag));
2012 if (!locallock || locallock->
nLocks <= 0)
2035 if (lockOwners[i].owner == owner)
2037 Assert(lockOwners[i].nLocks > 0);
2038 if (--lockOwners[i].nLocks == 0)
2044 if (i < locallock->numLockOwners)
2065 if (locallock->
nLocks > 0)
2113 lock = locallock->
lock;
2125 elog(
ERROR,
"failed to re-find shared lock object");
2126 locallock->
lock = lock;
2128 proclocktag.
myLock = lock;
2131 (
void *) &proclocktag,
2135 elog(
ERROR,
"failed to re-find shared proclock object");
2137 LOCK_PRINT(
"LockRelease: found", lock, lockmode);
2158 wakeupNeeded =
UnGrantLock(lock, lockmode, proclock, lockMethodTable);
2161 lockMethodTable, locallock->
hashcode,
2189 bool have_fast_path_lwlock =
false;
2191 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
2192 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2193 lockMethodTable = LockMethods[lockmethodid];
2197 elog(
LOG,
"LockReleaseAll: lockmethod=%d", lockmethodid);
2228 if (locallock->
nLocks == 0)
2250 if (lockOwners[i].owner == NULL)
2251 lockOwners[0] = lockOwners[
i];
2257 lockOwners[0].
owner == NULL &&
2258 lockOwners[0].
nLocks > 0)
2274 if (locallock->
proclock == NULL || locallock->
lock == NULL)
2281 elog(
PANIC,
"locallock table corrupted");
2291 if (!have_fast_path_lwlock)
2294 have_fast_path_lwlock =
true;
2311 have_fast_path_lwlock =
false;
2321 &locallock->
tag.
lock, lockmode,
false);
2327 if (locallock->
nLocks > 0)
2335 if (have_fast_path_lwlock)
2377 proclock = nextplock)
2379 bool wakeupNeeded =
false;
2420 for (i = 1; i <= numLockModes; i++)
2428 LOCK_PRINT(
"LockReleaseAll: updated", lock, 0);
2444 elog(
LOG,
"LockReleaseAll done");
2458 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
2459 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2485 if (locallocks == NULL)
2499 for (i = nlocks - 1; i >= 0; i--)
2534 if (lockOwners[i].owner == owner)
2536 Assert(lockOwners[i].nLocks > 0);
2537 if (lockOwners[i].nLocks < locallock->nLocks)
2548 if (i < locallock->numLockOwners)
2584 if (locallocks == NULL)
2598 for (i = nlocks - 1; i >= 0; i--)
2624 else if (lockOwners[i].owner == parent)
2634 lockOwners[ic].
owner = parent;
2643 if (ic < locallock->numLockOwners)
2673 if (unused_slot < FP_LOCK_SLOTS_PER_BACKEND)
2694 bool result =
false;
2781 hashcode, lockmode);
2829 lockmode = locallock->
tag.
mode;
2843 (
errcode(ERRCODE_OUT_OF_MEMORY),
2844 errmsg(
"out of shared memory"),
2845 errhint(
"You might need to increase max_locks_per_transaction.")));
2859 if (proclock == NULL)
2863 uint32 proclock_hashcode;
2873 elog(
ERROR,
"failed to re-find shared lock object");
2875 proclocktag.
myLock = lock;
2881 (
void *) &proclocktag,
2886 elog(
ERROR,
"failed to re-find shared proclock object");
2925 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
2926 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
2927 lockMethodTable = LockMethods[lockmethodid];
2928 if (lockmode <= 0 || lockmode > lockMethodTable->
numLockModes)
2929 elog(
ERROR,
"unrecognized lock mode: %d", lockmode);
3003 if (relid != proc->
fpRelId[f])
3014 if ((lockmask & conflictMask) == 0)
3026 vxids[count++] = vxid;
3074 if (conflictMask & proclock->
holdMask)
3095 for (i = 0; i < fast_count; ++
i)
3098 if (i >= fast_count)
3099 vxids[count++] = vxid;
3111 elog(
PANIC,
"too many conflicting locks found");
3134 bool decrement_strong_lock_count)
3140 uint32 proclock_hashcode;
3158 elog(
PANIC,
"failed to re-find shared lock object");
3163 proclocktag.
myLock = lock;
3164 proclocktag.
myProc = proc;
3169 (
void *) &proclocktag,
3174 elog(
PANIC,
"failed to re-find shared proclock object");
3192 wakeupNeeded =
UnGrantLock(lock, lockmode, proclock, lockMethodTable);
3195 lockMethodTable, hashcode,
3203 if (decrement_strong_lock_count
3209 Assert(FastPathStrongRelationLocks->
count[fasthashcode] > 0);
3210 FastPathStrongRelationLocks->
count[fasthashcode]--;
3246 bool haveSessionLock;
3258 if (locallock->
nLocks <= 0)
3262 haveSessionLock = haveXactLock =
false;
3265 if (lockOwners[i].owner == NULL)
3266 haveSessionLock =
true;
3268 haveXactLock =
true;
3288 if (haveSessionLock)
3290 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3291 errmsg(
"cannot PREPARE while holding both session-level and transaction-level locks on the same object")));
3370 bool haveSessionLock;
3374 if (locallock->
proclock == NULL || locallock->
lock == NULL)
3390 haveSessionLock = haveXactLock =
false;
3393 if (lockOwners[i].owner == NULL)
3394 haveSessionLock =
true;
3396 haveXactLock =
true;
3404 if (haveSessionLock)
3406 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3407 errmsg(
"cannot PREPARE while holding both session-level and transaction-level locks on the same object")));
3410 if (locallock->
nLocks > 0)
3445 proclock = nextplock)
3473 elog(
PANIC,
"we seem to have dropped a bit somewhere");
3493 proclocktag.
myLock = lock;
3494 proclocktag.
myProc = newproc;
3510 (
void *) &proclocktag))
3511 elog(
PANIC,
"duplicate entry found while reassigning a prepared transaction's locks");
3515 &proclock->procLink);
3534 long max_table_size;
3541 max_table_size *= 2;
3619 instance = &data->
locks[el];
3626 instance->
pid = proc->
pid;
3648 instance = &data->
locks[el];
3654 instance->
pid = proc->
pid;
3706 instance->
pid = proc->
pid;
3720 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
3819 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
3844 if (theLock == NULL)
3849 bproc->
pid = blocked_proc->
pid;
3884 instance->
pid = proc->
pid;
3895 queue_size = waitQueue->
size;
3900 data->
npids + queue_size);
3907 for (i = 0; i < queue_size; i++)
3909 if (proc == blocked_proc)
3988 accessExclusiveLocks[index].
xid = xid;
4005 for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
4009 return accessExclusiveLocks;
4016 Assert(lockmethodid > 0 && lockmethodid <
lengthof(LockMethods));
4017 Assert(mode > 0 && mode <= LockMethods[lockmethodid]->numLockModes);
4092 elog(
LOG,
"DumpAllLocks: proclock->tag.myLock = NULL");
4128 void *recdata,
uint32 len)
4140 uint32 proclock_hashcode;
4150 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
4151 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4152 lockMethodTable = LockMethods[lockmethodid];
4172 (
errcode(ERRCODE_OUT_OF_MEMORY),
4173 errmsg(
"out of shared memory"),
4174 errhint(
"You might need to increase max_locks_per_transaction.")));
4190 LOCK_PRINT(
"lock_twophase_recover: new", lock, lockmode);
4194 LOCK_PRINT(
"lock_twophase_recover: found", lock, lockmode);
4203 proclocktag.
myLock = lock;
4204 proclocktag.
myProc = proc;
4212 (
void *) &proclocktag,
4229 (
void *) &(lock->
tag),
4237 (
errcode(ERRCODE_OUT_OF_MEMORY),
4238 errmsg(
"out of shared memory"),
4239 errhint(
"You might need to increase max_locks_per_transaction.")));
4275 elog(
ERROR,
"lock %s on object %u/%u/%u is already held",
4296 FastPathStrongRelationLocks->
count[fasthashcode]++;
4309 void *recdata,
uint32 len)
4321 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
4322 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4341 void *recdata,
uint32 len)
4353 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
4354 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
4355 lockMethodTable = LockMethods[lockmethodid];
4367 void *recdata,
uint32 len)
4529 (
errcode(ERRCODE_OUT_OF_MEMORY),
4530 errmsg(
"out of shared memory"),
4531 errhint(
"You might need to increase max_locks_per_transaction.")));
4565 if (lockmethodid <= 0 || lockmethodid >=
lengthof(LockMethods))
4566 elog(
ERROR,
"unrecognized lock method: %d", lockmethodid);
static void LockReassignOwner(LOCALLOCK *locallock, ResourceOwner parent)
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
static PgChecksumMode mode
void hash_destroy(HTAB *hashp)
static const LockMethodData user_lockmethod
static HTAB * LockMethodLocalHash
bool holdsStrongLockCount
static void LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc, LOCKTAG *locktag, LOCKMODE lockmode, bool decrement_strong_lock_count)
int errhint(const char *fmt,...)
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
void VirtualXactLockTableCleanup(void)
const char * GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
void lock_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
static bool FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode)
static PROCLOCK * SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode)
#define ConflictsWithRelationFastPath(locktag, mode)
#define GET_VXID_FROM_PGPROC(vxid, proc)
static bool FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode)
void GrantAwaitedLock(void)
static PROCLOCK * FastPathGetRelationLockEntry(LOCALLOCK *locallock)
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode)
BlockedProcsData * GetBlockerStatusData(int blocked_pid)
dlist_head lockGroupMembers
bool update_process_title
#define PointerGetDatum(X)
void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode)
#define dlist_foreach(iter, lhead)
ResourceOwner CurrentResourceOwner
#define SpinLockInit(lock)
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS]
#define END_CRIT_SECTION()
#define FAST_PATH_GET_BITS(proc, n)
static int FastPathLocalUseCount
const LOCKMASK * conflictTab
#define LockHashPartitionLock(hashcode)
static const char *const lock_mode_names[]
static uint32 proclock_hash(const void *key, Size keysize)
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
#define START_CRIT_SECTION()
int errcode(int sqlerrcode)
#define MemSet(start, val, len)
#define FastPathStrongLockHashPartition(hashcode)
long hash_get_num_entries(HTAB *hashp)
#define LockHashPartition(hashcode)
void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem)
static HTAB * LockMethodProcLockHash
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
static LOCALLOCK * StrongLockInProgress
ProcWaitStatus waitStatus
bool RecoveryInProgress(void)
LocalTransactionId localTransactionId
#define EligibleForRelationFastPath(locktag, mode)
struct LOCALLOCKTAG LOCALLOCKTAG
static LOCALLOCK * awaitedLock
void lock_twophase_standby_recover(TransactionId xid, uint16 info, void *recdata, uint32 len)
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
#define LOCALLOCK_LOCKTAG(llock)
#define FirstNormalObjectId
void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, const void *data, uint32 len)
static void WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
#define DEFAULT_LOCKMETHOD
void LWLockRelease(LWLock *lock)
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
void lock_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len)
#define PROCLOCK_LOCKMETHOD(proclock)
#define VirtualTransactionIdEquals(vxid1, vxid2)
void set_ps_display(const char *activity)
void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)
#define FAST_PATH_CHECK_LOCKMODE(proc, n, l)
PGPROC * BackendPidGetProcWithLock(int pid)
static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
#define SpinLockAcquire(lock)
#define LOCKBIT_OFF(lockmode)
#define dlist_container(type, membername, ptr)
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
#define LockHashPartitionLockByIndex(i)
struct LOCALLOCK LOCALLOCK
void pfree(void *pointer)
static const LockMethodData default_lockmethod
#define LOCK_LOCKTAG(lock)
static volatile FastPathStrongRelationLockData * FastPathStrongRelationLocks
static void RemoveLocalLock(LOCALLOCK *locallock)
static void ReleaseLockIfHeld(LOCALLOCK *locallock, bool sessionLock)
ProcWaitStatus ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void PostPrepare_Locks(TransactionId xid)
static uint32 ProcLockHashCode(const PROCLOCKTAG *proclocktag, uint32 hashcode)
static void FinishStrongLockAcquire(void)
#define FAST_PATH_SET_LOCKMODE(proc, n, l)
void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
const char * get_ps_display(int *displen)
LockData * GetLockStatusData(void)
#define FP_LOCK_SLOTS_PER_BACKEND
bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2)
void ProcQueueInit(PROC_QUEUE *queue)
void LogAccessExclusiveLockPrepare(void)
void AbortStrongLockAcquire(void)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
int granted[MAX_LOCKMODES]
uint32 LocalTransactionId
PGPROC * TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
uint32 LockTagHashCode(const LOCKTAG *locktag)
#define LOCALLOCK_LOCKMETHOD(llock)
MemoryContext TopMemoryContext
#define VirtualTransactionIdIsValid(vxid)
bool SHMQueueEmpty(const SHM_QUEUE *queue)
Size hash_estimate_size(long num_entries, Size entrysize)
#define FAST_PATH_STRONG_LOCK_HASH_PARTITIONS
#define SpinLockRelease(lock)
int requested[MAX_LOCKMODES]
void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
static const LOCKMASK LockConflicts[]
void * palloc0(Size size)
ResourceOwner ResourceOwnerGetParent(ResourceOwner owner)
struct PROCLOCKTAG PROCLOCKTAG
static void CheckAndSetLockHeld(LOCALLOCK *locallock, bool acquired)
Size add_size(Size s1, Size s2)
Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, Size linkOffset)
void ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock)
static ResourceOwner awaitedOwner
static void BeginStrongLockAcquire(LOCALLOCK *locallock, uint32 fasthashcode)
void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode)
#define XLogStandbyInfoActive()
#define LOCK_PRINT(where, lock, type)
LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag)
void DeadLockReport(void)
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
#define ereport(elevel,...)
bool LockCheckConflicts(LockMethod lockMethodTable, LOCKMODE lockmode, LOCK *lock, PROCLOCK *proclock)
#define ShareUpdateExclusiveLock
Oid fpRelId[FP_LOCK_SLOTS_PER_BACKEND]
#define Assert(condition)
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
#define ShareRowExclusiveLock
void AtPrepare_Locks(void)
static HTAB * LockMethodLockHash
void LockReleaseSession(LOCKMETHODID lockmethodid)
#define TWOPHASE_RM_LOCK_ID
LOCALLOCKOWNER * lockOwners
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag, vxid)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
bool hash_update_hash_key(HTAB *hashp, void *existingEntry, const void *newKeyPtr)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void * repalloc(void *pointer, Size size)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
uint8 locktag_lockmethodid
#define FAST_PATH_LOCKNUMBER_OFFSET
int LockWaiterCount(const LOCKTAG *locktag)
#define LOCKBIT_ON(lockmode)
void MarkLockClear(LOCALLOCK *locallock)
static bool IsRelationExtensionLockHeld PG_USED_FOR_ASSERTS_ONLY
#define AccessExclusiveLock
int errmsg(const char *fmt,...)
void SHMQueueInit(SHM_QUEUE *queue)
void * MemoryContextAlloc(MemoryContext context, Size size)
void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
#define InvalidLocalTransactionId
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
#define LocalTransactionIdIsValid(lxid)
bool LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
void lock_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len)
void SHMQueueDelete(SHM_QUEUE *queue)
struct ResourceOwnerData * owner
static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode, PROCLOCK *proclock, LockMethod lockMethodTable)
static const LockMethod LockMethods[]
SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS]
#define PROCLOCK_PRINT(where, proclockP)
HTAB * ShmemInitHash(const char *name, long init_size, long max_size, HASHCTL *infoP, int hash_flags)
static void CleanUpLock(LOCK *lock, PROCLOCK *proclock, LockMethod lockMethodTable, uint32 hashcode, bool wakeupNeeded)
#define TransactionIdIsValid(xid)
static bool FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag, uint32 hashcode)
#define FAST_PATH_BITS_PER_SLOT
static void static void status(const char *fmt,...) pg_attribute_printf(1
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError, LOCALLOCK **locallockp)
void ResourceOwnerRememberLock(ResourceOwner owner, LOCALLOCK *locallock)
LockMethod GetLocksMethodTable(const LOCK *lock)
#define LOG2_NUM_LOCK_PARTITIONS
LocalTransactionId fpLocalTransactionId
static void GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner)
#define offsetof(type, field)
const char *const * lockModeNames
#define NUM_LOCK_PARTITIONS
#define FAST_PATH_CLEAR_LOCKMODE(proc, n, l)
struct TwoPhaseLockRecord TwoPhaseLockRecord
PGPROC * BackendIdGetProc(int backendID)
#define LOCK_LOCKMETHOD(lock)