1 /*-------------------------------------------------------------------------
2  *
3  * lock.h
4  *	  POSTGRES low-level lock mechanism
5  *
6  *
7  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/storage/lock.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef LOCK_H_
15 #define LOCK_H_
16 
17 #ifdef FRONTEND
18 #error "lock.h may not be included from frontend code"
19 #endif
20 
21 #include "storage/backendid.h"
22 #include "storage/lockdefs.h"
23 #include "storage/lwlock.h"
24 #include "storage/shmem.h"
25 
26 /* struct PGPROC is declared in proc.h, but must forward-reference it */
27 typedef struct PGPROC PGPROC;
28 
29 typedef struct PROC_QUEUE
30 {
31 	SHM_QUEUE	links;			/* head of list of PGPROC objects */
32 	int			size;			/* number of entries in list */
33 } PROC_QUEUE;
34 
35 /* GUC variables */
36 extern int	max_locks_per_xact;
37 
38 #ifdef LOCK_DEBUG
39 extern int	Trace_lock_oidmin;
40 extern bool Trace_locks;
41 extern bool Trace_userlocks;
42 extern int	Trace_lock_table;
43 extern bool Debug_deadlocks;
44 #endif							/* LOCK_DEBUG */
45 
46 
47 /*
48  * Top-level transactions are identified by VirtualTransactionIDs comprising
49  * PGPROC fields backendId and lxid.  For recovered prepared transactions, the
50  * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never
51  * refers to that kind.  These are guaranteed unique over the short term, but
52  * will be reused after a database restart or XID wraparound; hence they
53  * should never be stored on disk.
54  *
55  * Note that struct VirtualTransactionId can not be assumed to be atomically
56  * assignable as a whole.  However, type LocalTransactionId is assumed to
57  * be atomically assignable, and the backend ID doesn't change often enough
58  * to be a problem, so we can fetch or assign the two fields separately.
59  * We deliberately refrain from using the struct within PGPROC, to prevent
60  * coding errors from trying to use struct assignment with it; instead use
61  * GET_VXID_FROM_PGPROC().
62  */
63 typedef struct
64 {
65 	BackendId	backendId;		/* backendId from PGPROC */
66 	LocalTransactionId localTransactionId;	/* lxid from PGPROC */
67 } VirtualTransactionId;
68 
69 #define InvalidLocalTransactionId		0
70 #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
71 #define VirtualTransactionIdIsValid(vxid) \
72 	(LocalTransactionIdIsValid((vxid).localTransactionId))
73 #define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \
74 	((vxid).backendId == InvalidBackendId)
75 #define VirtualTransactionIdEquals(vxid1, vxid2) \
76 	((vxid1).backendId == (vxid2).backendId && \
77 	 (vxid1).localTransactionId == (vxid2).localTransactionId)
78 #define SetInvalidVirtualTransactionId(vxid) \
79 	((vxid).backendId = InvalidBackendId, \
80 	 (vxid).localTransactionId = InvalidLocalTransactionId)
81 #define GET_VXID_FROM_PGPROC(vxid, proc) \
82 	((vxid).backendId = (proc).backendId, \
83 	 (vxid).localTransactionId = (proc).lxid)
84 
85 /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
86 #define MAX_LOCKMODES		10
87 
88 #define LOCKBIT_ON(lockmode) (1 << (lockmode))
89 #define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
90 
91 
92 /*
93  * This data structure defines the locking semantics associated with a
94  * "lock method".  The semantics specify the meaning of each lock mode
95  * (by defining which lock modes it conflicts with).
96  * All of this data is constant and is kept in const tables.
97  *
98  * numLockModes -- number of lock modes (READ,WRITE,etc) that
99  *		are defined in this lock method.  Must be less than MAX_LOCKMODES.
100  *
101  * conflictTab -- this is an array of bitmasks showing lock
102  *		mode conflicts.  conflictTab[i] is a mask with the j-th bit
103  *		turned on if lock modes i and j conflict.  Lock modes are
104  *		numbered 1..numLockModes; conflictTab[0] is unused.
105  *
106  * lockModeNames -- ID strings for debug printouts.
107  *
108  * trace_flag -- pointer to GUC trace flag for this lock method.  (The
109  * GUC variable is not constant, but we use "const" here to denote that
110  * it can't be changed through this reference.)
111  */
112 typedef struct LockMethodData
113 {
114 	int			numLockModes;
115 	const LOCKMASK *conflictTab;
116 	const char *const *lockModeNames;
117 	const bool *trace_flag;
118 } LockMethodData;
119 
120 typedef const LockMethodData *LockMethod;
121 
122 /*
123  * Lock methods are identified by LOCKMETHODID.  (Despite the declaration as
124  * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
125  */
126 typedef uint16 LOCKMETHODID;
127 
128 /* These identify the known lock methods */
129 #define DEFAULT_LOCKMETHOD	1
130 #define USER_LOCKMETHOD		2
131 
132 /*
133  * LOCKTAG is the key information needed to look up a LOCK item in the
134  * lock hashtable.  A LOCKTAG value uniquely identifies a lockable object.
135  *
136  * The LockTagType enum defines the different kinds of objects we can lock.
137  * We can handle up to 256 different LockTagTypes.
138  */
139 typedef enum LockTagType
140 {
141 	LOCKTAG_RELATION,			/* whole relation */
142 	LOCKTAG_RELATION_EXTEND,	/* the right to extend a relation */
143 	LOCKTAG_DATABASE_FROZEN_IDS,	/* pg_database.datfrozenxid */
144 	LOCKTAG_PAGE,				/* one page of a relation */
145 	LOCKTAG_TUPLE,				/* one physical tuple */
146 	LOCKTAG_TRANSACTION,		/* transaction (for waiting for xact done) */
147 	LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
148 	LOCKTAG_SPECULATIVE_TOKEN,	/* speculative insertion Xid and token */
149 	LOCKTAG_OBJECT,				/* non-relation database object */
150 	LOCKTAG_USERLOCK,			/* reserved for old contrib/userlock code */
151 	LOCKTAG_ADVISORY			/* advisory user locks */
152 } LockTagType;
153 
154 #define LOCKTAG_LAST_TYPE	LOCKTAG_ADVISORY
155 
156 extern const char *const LockTagTypeNames[];
157 
158 /*
159  * The LOCKTAG struct is defined with malice aforethought to fit into 16
160  * bytes with no padding.  Note that this would need adjustment if we were
161  * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
162  *
163  * We include lockmethodid in the locktag so that a single hash table in
164  * shared memory can store locks of different lockmethods.
165  */
166 typedef struct LOCKTAG
167 {
168 	uint32		locktag_field1; /* a 32-bit ID field */
169 	uint32		locktag_field2; /* a 32-bit ID field */
170 	uint32		locktag_field3; /* a 32-bit ID field */
171 	uint16		locktag_field4; /* a 16-bit ID field */
172 	uint8		locktag_type;	/* see enum LockTagType */
173 	uint8		locktag_lockmethodid;	/* lockmethod indicator */
174 } LOCKTAG;
175 
176 /*
177  * These macros define how we map logical IDs of lockable objects into
178  * the physical fields of LOCKTAG.  Use these to set up LOCKTAG values,
179  * rather than accessing the fields directly.  Note multiple eval of target!
180  */
181 
182 /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
183 #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
184 	((locktag).locktag_field1 = (dboid), \
185 	 (locktag).locktag_field2 = (reloid), \
186 	 (locktag).locktag_field3 = 0, \
187 	 (locktag).locktag_field4 = 0, \
188 	 (locktag).locktag_type = LOCKTAG_RELATION, \
189 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
190 
191 /* same ID info as RELATION */
192 #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
193 	((locktag).locktag_field1 = (dboid), \
194 	 (locktag).locktag_field2 = (reloid), \
195 	 (locktag).locktag_field3 = 0, \
196 	 (locktag).locktag_field4 = 0, \
197 	 (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
198 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
199 
200 /* ID info for frozen IDs is DB OID */
201 #define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
202 	((locktag).locktag_field1 = (dboid), \
203 	 (locktag).locktag_field2 = 0, \
204 	 (locktag).locktag_field3 = 0, \
205 	 (locktag).locktag_field4 = 0, \
206 	 (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
207 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
208 
209 /* ID info for a page is RELATION info + BlockNumber */
210 #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
211 	((locktag).locktag_field1 = (dboid), \
212 	 (locktag).locktag_field2 = (reloid), \
213 	 (locktag).locktag_field3 = (blocknum), \
214 	 (locktag).locktag_field4 = 0, \
215 	 (locktag).locktag_type = LOCKTAG_PAGE, \
216 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
217 
218 /* ID info for a tuple is PAGE info + OffsetNumber */
219 #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
220 	((locktag).locktag_field1 = (dboid), \
221 	 (locktag).locktag_field2 = (reloid), \
222 	 (locktag).locktag_field3 = (blocknum), \
223 	 (locktag).locktag_field4 = (offnum), \
224 	 (locktag).locktag_type = LOCKTAG_TUPLE, \
225 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
226 
227 /* ID info for a transaction is its TransactionId */
228 #define SET_LOCKTAG_TRANSACTION(locktag,xid) \
229 	((locktag).locktag_field1 = (xid), \
230 	 (locktag).locktag_field2 = 0, \
231 	 (locktag).locktag_field3 = 0, \
232 	 (locktag).locktag_field4 = 0, \
233 	 (locktag).locktag_type = LOCKTAG_TRANSACTION, \
234 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
235 
236 /* ID info for a virtual transaction is its VirtualTransactionId */
237 #define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
238 	((locktag).locktag_field1 = (vxid).backendId, \
239 	 (locktag).locktag_field2 = (vxid).localTransactionId, \
240 	 (locktag).locktag_field3 = 0, \
241 	 (locktag).locktag_field4 = 0, \
242 	 (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
243 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
244 
245 /*
246  * ID info for a speculative insert is TRANSACTION info +
247  * its speculative insert counter.
248  */
249 #define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \
250 	((locktag).locktag_field1 = (xid), \
251 	 (locktag).locktag_field2 = (token),		\
252 	 (locktag).locktag_field3 = 0, \
253 	 (locktag).locktag_field4 = 0, \
254 	 (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \
255 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
256 
257 /*
258  * ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID
259  *
260  * Note: object ID has same representation as in pg_depend and
261  * pg_description, but notice that we are constraining SUBID to 16 bits.
262  * Also, we use DB OID = 0 for shared objects such as tablespaces.
263  */
264 #define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
265 	((locktag).locktag_field1 = (dboid), \
266 	 (locktag).locktag_field2 = (classoid), \
267 	 (locktag).locktag_field3 = (objoid), \
268 	 (locktag).locktag_field4 = (objsubid), \
269 	 (locktag).locktag_type = LOCKTAG_OBJECT, \
270 	 (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
271 
272 #define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
273 	((locktag).locktag_field1 = (id1), \
274 	 (locktag).locktag_field2 = (id2), \
275 	 (locktag).locktag_field3 = (id3), \
276 	 (locktag).locktag_field4 = (id4), \
277 	 (locktag).locktag_type = LOCKTAG_ADVISORY, \
278 	 (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
279 
280 
281 /*
282  * Per-locked-object lock information:
283  *
284  * tag -- uniquely identifies the object being locked
285  * grantMask -- bitmask for all lock types currently granted on this object.
286  * waitMask -- bitmask for all lock types currently awaited on this object.
287  * procLocks -- list of PROCLOCK objects for this lock.
288  * waitProcs -- queue of processes waiting for this lock.
289  * requested -- count of each lock type currently requested on the lock
290  *		(includes requests already granted!!).
291  * nRequested -- total requested locks of all types.
292  * granted -- count of each lock type currently granted on the lock.
293  * nGranted -- total granted locks of all types.
294  *
295  * Note: these counts count 1 for each backend.  Internally to a backend,
296  * there may be multiple grabs on a particular lock, but this is not reflected
297  * into shared memory.
298  */
299 typedef struct LOCK
300 {
301 	/* hash key */
302 	LOCKTAG		tag;			/* unique identifier of lockable object */
303 
304 	/* data */
305 	LOCKMASK	grantMask;		/* bitmask for lock types already granted */
306 	LOCKMASK	waitMask;		/* bitmask for lock types awaited */
307 	SHM_QUEUE	procLocks;		/* list of PROCLOCK objects assoc. with lock */
308 	PROC_QUEUE	waitProcs;		/* list of PGPROC objects waiting on lock */
309 	int			requested[MAX_LOCKMODES];	/* counts of requested locks */
310 	int			nRequested;		/* total of requested[] array */
311 	int			granted[MAX_LOCKMODES]; /* counts of granted locks */
312 	int			nGranted;		/* total of granted[] array */
313 } LOCK;
314 
315 #define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
316 #define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type)
317 
318 
319 /*
320  * We may have several different backends holding or awaiting locks
321  * on the same lockable object.  We need to store some per-holder/waiter
322  * information for each such holder (or would-be holder).  This is kept in
323  * a PROCLOCK struct.
324  *
325  * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
326  * proclock hashtable.  A PROCLOCKTAG value uniquely identifies the combination
327  * of a lockable object and a holder/waiter for that object.  (We can use
328  * pointers here because the PROCLOCKTAG need only be unique for the lifespan
329  * of the PROCLOCK, and it will never outlive the lock or the proc.)
330  *
331  * Internally to a backend, it is possible for the same lock to be held
332  * for different purposes: the backend tracks transaction locks separately
333  * from session locks.  However, this is not reflected in the shared-memory
334  * state: we only track which backend(s) hold the lock.  This is OK since a
335  * backend can never block itself.
336  *
337  * The holdMask field shows the already-granted locks represented by this
338  * proclock.  Note that there will be a proclock object, possibly with
339  * zero holdMask, for any lock that the process is currently waiting on.
340  * Otherwise, proclock objects whose holdMasks are zero are recycled
341  * as soon as convenient.
342  *
343  * releaseMask is workspace for LockReleaseAll(): it shows the locks due
344  * to be released during the current call.  This must only be examined or
345  * set by the backend owning the PROCLOCK.
346  *
347  * Each PROCLOCK object is linked into lists for both the associated LOCK
348  * object and the owning PGPROC object.  Note that the PROCLOCK is entered
349  * into these lists as soon as it is created, even if no lock has yet been
350  * granted.  A PGPROC that is waiting for a lock to be granted will also be
351  * linked into the lock's waitProcs queue.
352  */
353 typedef struct PROCLOCKTAG
354 {
355 	/* NB: we assume this struct contains no padding! */
356 	LOCK	   *myLock;			/* link to per-lockable-object information */
357 	PGPROC	   *myProc;			/* link to PGPROC of owning backend */
358 } PROCLOCKTAG;
359 
360 typedef struct PROCLOCK
361 {
362 	/* tag */
363 	PROCLOCKTAG tag;			/* unique identifier of proclock object */
364 
365 	/* data */
366 	PGPROC	   *groupLeader;	/* proc's lock group leader, or proc itself */
367 	LOCKMASK	holdMask;		/* bitmask for lock types currently held */
368 	LOCKMASK	releaseMask;	/* bitmask for lock types to be released */
369 	SHM_QUEUE	lockLink;		/* list link in LOCK's list of proclocks */
370 	SHM_QUEUE	procLink;		/* list link in PGPROC's list of proclocks */
371 } PROCLOCK;
372 
373 #define PROCLOCK_LOCKMETHOD(proclock) \
374 	LOCK_LOCKMETHOD(*((proclock).tag.myLock))
375 
376 /*
377  * Each backend also maintains a local hash table with information about each
378  * lock it is currently interested in.  In particular the local table counts
379  * the number of times that lock has been acquired.  This allows multiple
380  * requests for the same lock to be executed without additional accesses to
381  * shared memory.  We also track the number of lock acquisitions per
382  * ResourceOwner, so that we can release just those locks belonging to a
383  * particular ResourceOwner.
384  *
385  * When holding a lock taken "normally", the lock and proclock fields always
386  * point to the associated objects in shared memory.  However, if we acquired
387  * the lock via the fast-path mechanism, the lock and proclock fields are set
388  * to NULL, since there probably aren't any such objects in shared memory.
389  * (If the lock later gets promoted to normal representation, we may eventually
390  * update our locallock's lock/proclock fields after finding the shared
391  * objects.)
392  *
393  * Caution: a locallock object can be left over from a failed lock acquisition
394  * attempt.  In this case its lock/proclock fields are untrustworthy, since
395  * the shared lock object is neither held nor awaited, and hence is available
396  * to be reclaimed.  If nLocks > 0 then these pointers must either be valid or
397  * NULL, but when nLocks == 0 they should be considered garbage.
398  */
399 typedef struct LOCALLOCKTAG
400 {
401 	LOCKTAG		lock;			/* identifies the lockable object */
402 	LOCKMODE	mode;			/* lock mode for this table entry */
403 } LOCALLOCKTAG;
404 
405 typedef struct LOCALLOCKOWNER
406 {
407 	/*
408 	 * Note: if owner is NULL then the lock is held on behalf of the session;
409 	 * otherwise it is held on behalf of my current transaction.
410 	 *
411 	 * Must use a forward struct reference to avoid circularity.
412 	 */
413 	struct ResourceOwnerData *owner;
414 	int64		nLocks;			/* # of times held by this owner */
415 } LOCALLOCKOWNER;
416 
417 typedef struct LOCALLOCK
418 {
419 	/* tag */
420 	LOCALLOCKTAG tag;			/* unique identifier of locallock entry */
421 
422 	/* data */
423 	uint32		hashcode;		/* copy of LOCKTAG's hash value */
424 	LOCK	   *lock;			/* associated LOCK object, if any */
425 	PROCLOCK   *proclock;		/* associated PROCLOCK object, if any */
426 	int64		nLocks;			/* total number of times lock is held */
427 	int			numLockOwners;	/* # of relevant ResourceOwners */
428 	int			maxLockOwners;	/* allocated size of array */
429 	LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
430 	bool		holdsStrongLockCount;	/* bumped FastPathStrongRelationLocks */
431 	bool		lockCleared;	/* we read all sinval msgs for lock */
432 } LOCALLOCK;
433 
434 #define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
435 #define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)
436 
437 
438 /*
439  * These structures hold information passed from lmgr internals to the lock
440  * listing user-level functions (in lockfuncs.c).
441  */
442 
443 typedef struct LockInstanceData
444 {
445 	LOCKTAG		locktag;		/* tag for locked object */
446 	LOCKMASK	holdMask;		/* locks held by this PGPROC */
447 	LOCKMODE	waitLockMode;	/* lock awaited by this PGPROC, if any */
448 	BackendId	backend;		/* backend ID of this PGPROC */
449 	LocalTransactionId lxid;	/* local transaction ID of this PGPROC */
450 	int			pid;			/* pid of this PGPROC */
451 	int			leaderPid;		/* pid of group leader; = pid if no group */
452 	bool		fastpath;		/* taken via fastpath? */
453 } LockInstanceData;
454 
455 typedef struct LockData
456 {
457 	int			nelements;		/* The length of the array */
458 	LockInstanceData *locks;	/* Array of per-PROCLOCK information */
459 } LockData;
460 
461 typedef struct BlockedProcData
462 {
463 	int			pid;			/* pid of a blocked PGPROC */
464 	/* Per-PROCLOCK information about PROCLOCKs of the lock the pid awaits */
465 	/* (these fields refer to indexes in BlockedProcsData.locks[]) */
466 	int			first_lock;		/* index of first relevant LockInstanceData */
467 	int			num_locks;		/* number of relevant LockInstanceDatas */
468 	/* PIDs of PGPROCs that are ahead of "pid" in the lock's wait queue */
469 	/* (these fields refer to indexes in BlockedProcsData.waiter_pids[]) */
470 	int			first_waiter;	/* index of first preceding waiter */
471 	int			num_waiters;	/* number of preceding waiters */
472 } BlockedProcData;
473 
474 typedef struct BlockedProcsData
475 {
476 	BlockedProcData *procs;		/* Array of per-blocked-proc information */
477 	LockInstanceData *locks;	/* Array of per-PROCLOCK information */
478 	int		   *waiter_pids;	/* Array of PIDs of other blocked PGPROCs */
479 	int			nprocs;			/* # of valid entries in procs[] array */
480 	int			maxprocs;		/* Allocated length of procs[] array */
481 	int			nlocks;			/* # of valid entries in locks[] array */
482 	int			maxlocks;		/* Allocated length of locks[] array */
483 	int			npids;			/* # of valid entries in waiter_pids[] array */
484 	int			maxpids;		/* Allocated length of waiter_pids[] array */
485 } BlockedProcsData;
486 
487 
488 /* Result codes for LockAcquire() */
489 typedef enum
490 {
491 	LOCKACQUIRE_NOT_AVAIL,		/* lock not available, and dontWait=true */
492 	LOCKACQUIRE_OK,				/* lock successfully acquired */
493 	LOCKACQUIRE_ALREADY_HELD,	/* incremented count for lock already held */
494 	LOCKACQUIRE_ALREADY_CLEAR	/* incremented count for lock already clear */
495 } LockAcquireResult;
496 
497 /* Deadlock states identified by DeadLockCheck() */
498 typedef enum
499 {
500 	DS_NOT_YET_CHECKED,			/* no deadlock check has run yet */
501 	DS_NO_DEADLOCK,				/* no deadlock detected */
502 	DS_SOFT_DEADLOCK,			/* deadlock avoided by queue rearrangement */
503 	DS_HARD_DEADLOCK,			/* deadlock, no way out but ERROR */
504 	DS_BLOCKED_BY_AUTOVACUUM	/* no deadlock; queue blocked by autovacuum
505 								 * worker */
506 } DeadLockState;
507 
508 /*
509  * The lockmgr's shared hash tables are partitioned to reduce contention.
510  * To determine which partition a given locktag belongs to, compute the tag's
511  * hash code with LockTagHashCode(), then apply one of these macros.
512  * NB: NUM_LOCK_PARTITIONS must be a power of 2!
513  */
514 #define LockHashPartition(hashcode) \
515 	((hashcode) % NUM_LOCK_PARTITIONS)
516 #define LockHashPartitionLock(hashcode) \
517 	(&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \
518 		LockHashPartition(hashcode)].lock)
519 #define LockHashPartitionLockByIndex(i) \
520 	(&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
521 
522 /*
523  * The deadlock detector needs to be able to access lockGroupLeader and
524  * related fields in the PGPROC, so we arrange for those fields to be protected
525  * by one of the lock hash partition locks.  Since the deadlock detector
526  * acquires all such locks anyway, this makes it safe for it to access these
527  * fields without doing anything extra.  To avoid contention as much as
528  * possible, we map different PGPROCs to different partition locks.  The lock
529  * used for a given lock group is determined by the group leader's pgprocno.
530  */
531 #define LockHashPartitionLockByProc(leader_pgproc) \
532 	LockHashPartitionLock((leader_pgproc)->pgprocno)
533 
534 /*
535  * function prototypes
536  */
537 extern void InitLocks(void);
538 extern LockMethod GetLocksMethodTable(const LOCK *lock);
539 extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag);
540 extern uint32 LockTagHashCode(const LOCKTAG *locktag);
541 extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2);
542 extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,
543 									 LOCKMODE lockmode,
544 									 bool sessionLock,
545 									 bool dontWait);
546 extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,
547 											 LOCKMODE lockmode,
548 											 bool sessionLock,
549 											 bool dontWait,
550 											 bool reportMemoryError,
551 											 LOCALLOCK **locallockp);
552 extern void AbortStrongLockAcquire(void);
553 extern void MarkLockClear(LOCALLOCK *locallock);
554 extern bool LockRelease(const LOCKTAG *locktag,
555 						LOCKMODE lockmode, bool sessionLock);
556 extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
557 extern void LockReleaseSession(LOCKMETHODID lockmethodid);
558 extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks);
559 extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks);
560 extern bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode);
561 #ifdef USE_ASSERT_CHECKING
562 extern HTAB *GetLockMethodLocalHash(void);
563 #endif
564 extern bool LockHasWaiters(const LOCKTAG *locktag,
565 						   LOCKMODE lockmode, bool sessionLock);
566 extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag,
567 											  LOCKMODE lockmode, int *countp);
568 extern void AtPrepare_Locks(void);
569 extern void PostPrepare_Locks(TransactionId xid);
570 extern bool LockCheckConflicts(LockMethod lockMethodTable,
571 							   LOCKMODE lockmode,
572 							   LOCK *lock, PROCLOCK *proclock);
573 extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
574 extern void GrantAwaitedLock(void);
575 extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
576 extern Size LockShmemSize(void);
577 extern LockData *GetLockStatusData(void);
578 extern BlockedProcsData *GetBlockerStatusData(int blocked_pid);
579 
580 extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
581 extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
582 
583 extern void lock_twophase_recover(TransactionId xid, uint16 info,
584 								  void *recdata, uint32 len);
585 extern void lock_twophase_postcommit(TransactionId xid, uint16 info,
586 									 void *recdata, uint32 len);
587 extern void lock_twophase_postabort(TransactionId xid, uint16 info,
588 									void *recdata, uint32 len);
589 extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
590 										  void *recdata, uint32 len);
591 
592 extern DeadLockState DeadLockCheck(PGPROC *proc);
593 extern PGPROC *GetBlockingAutoVacuumPgproc(void);
594 extern void DeadLockReport(void) pg_attribute_noreturn();
595 extern void RememberSimpleDeadLock(PGPROC *proc1,
596 								   LOCKMODE lockmode,
597 								   LOCK *lock,
598 								   PGPROC *proc2);
599 extern void InitDeadLockChecking(void);
600 
601 extern int	LockWaiterCount(const LOCKTAG *locktag);
602 
603 #ifdef LOCK_DEBUG
604 extern void DumpLocks(PGPROC *proc);
605 extern void DumpAllLocks(void);
606 #endif
607 
608 /* Lock a VXID (used to wait for a transaction to finish) */
609 extern void VirtualXactLockTableInsert(VirtualTransactionId vxid);
610 extern void VirtualXactLockTableCleanup(void);
611 extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait);
612 
613 #endif							/* LOCK_H_ */
614