lock.h 7.7 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * lock.h
4
 *	  POSTGRES low-level lock mechanism
5 6
 *
 *
B
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
8
 * Portions Copyright (c) 1994, Regents of the University of California
9
 *
B
Bruce Momjian 已提交
10
 * $Id: lock.h,v 1.63 2002/07/19 00:17:40 momjian Exp $
11 12 13 14 15 16
 *
 *-------------------------------------------------------------------------
 */
#ifndef LOCK_H_
#define LOCK_H_

17
#include "storage/itemptr.h"
18
#include "storage/lwlock.h"
B
Bruce Momjian 已提交
19
#include "storage/shmem.h"
20 21


22 23 24
/* originally in procq.h */
typedef struct PROC_QUEUE
{
J
Jan Wieck 已提交
25
	SHM_QUEUE	links;			/* head of list of PGPROC objects */
26
	int			size;			/* number of entries in list */
27 28
} PROC_QUEUE;

J
Jan Wieck 已提交
29 30
/* struct PGPROC is declared in storage/proc.h, but must forward-reference it */
typedef struct PGPROC PGPROC;
31 32


33 34
extern int	max_locks_per_xact;

35
#ifdef LOCK_DEBUG
B
Bruce Momjian 已提交
36
extern int	Trace_lock_oidmin;
37 38
extern bool Trace_locks;
extern bool Trace_userlocks;
B
Bruce Momjian 已提交
39
extern int	Trace_lock_table;
40
extern bool Debug_deadlocks;
41
#endif   /* LOCK_DEBUG */
42 43


44 45
typedef int LOCKMASK;

46 47
typedef int LOCKMODE;
typedef int LOCKMETHOD;
48

49
/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
50
#define MAX_LOCKMODES		10
51

52
/* MAX_LOCK_METHODS is the number of distinct lock control tables allowed */
53
#define MAX_LOCK_METHODS	3
54

M
 
Marc G. Fournier 已提交
55 56 57 58 59
#define INVALID_TABLEID		0

#define INVALID_LOCKMETHOD	INVALID_TABLEID
#define DEFAULT_LOCKMETHOD	1
#define USER_LOCKMETHOD		2
60

61 62 63
/*
 * There is normally only one lock method, the default one.
 * If user locks are enabled, an additional lock method is present.
B
Bruce Momjian 已提交
64
 *
65
 * This is the control structure for a lock table.	It
B
Bruce Momjian 已提交
66
 * lives in shared memory.	This information is the same
67
 * for all backends.
68
 *
B
Bruce Momjian 已提交
69 70 71 72
 * lockHash -- hash table holding per-locked-object lock information
 *
 * holderHash -- hash table holding per-lock-holder lock information
 *
73 74
 * lockmethod -- the handle used by the lock table's clients to
 *		refer to the type of lock table being used.
75
 *
76
 * numLockModes -- number of lock types (READ,WRITE,etc) that
77
 *		are defined on this lock table
78 79
 *
 * conflictTab -- this is an array of bitmasks showing lock
80 81
 *		type conflicts. conflictTab[i] is a mask with the j-th bit
 *		turned on if lock types i and j conflict.
82
 *
83
 * prio -- each lockmode has a priority, so, for example, waiting
84
 *		writers can be given priority over readers (to avoid
85
 *		starvation).  XXX this field is not actually used at present!
86
 *
87
 * masterLock -- synchronizes access to the table
B
Bruce Momjian 已提交
88
 *
89
 */
B
Bruce Momjian 已提交
90
typedef struct LOCKMETHODTABLE
91
{
B
Bruce Momjian 已提交
92 93
	HTAB	   *lockHash;
	HTAB	   *holderHash;
94
	LOCKMETHOD	lockmethod;
95 96 97
	int			numLockModes;
	int			conflictTab[MAX_LOCKMODES];
	int			prio[MAX_LOCKMODES];
98
	LWLockId	masterLock;
99
} LOCKMETHODTABLE;
100

M
 
Marc G. Fournier 已提交
101

102 103
/*
 * LOCKTAG is the key information needed to look up a LOCK item in the
B
Bruce Momjian 已提交
104
 * lock hashtable.	A LOCKTAG value uniquely identifies a lockable object.
105 106
 */
typedef struct LOCKTAG
107
{
108 109 110 111 112 113 114
	Oid			relId;
	Oid			dbId;
	union
	{
		BlockNumber blkno;
		TransactionId xid;
	}			objId;
115

116 117 118 119 120 121
	/*
	 * offnum should be part of objId.tupleId above, but would increase
	 * sizeof(LOCKTAG) and so moved here; currently used by userlocks
	 * only.
	 */
	OffsetNumber offnum;
122

123 124
	uint16		lockmethod;		/* needed by userlocks */
} LOCKTAG;
125 126 127


/*
128
 * Per-locked-object lock information:
129 130
 *
 * tag -- uniquely identifies the object being locked
131 132
 * grantMask -- bitmask for all lock types currently granted on this object.
 * waitMask -- bitmask for all lock types currently awaited on this object.
B
Bruce Momjian 已提交
133
 * lockHolders -- list of PROCLOCK objects for this lock.
134 135 136 137 138 139
 * waitProcs -- queue of processes waiting for this lock.
 * requested -- count of each lock type currently requested on the lock
 *		(includes requests already granted!!).
 * nRequested -- total requested locks of all types.
 * granted -- count of each lock type currently granted on the lock.
 * nGranted -- total granted locks of all types.
140
 */
141
typedef struct LOCK
142 143
{
	/* hash key */
144
	LOCKTAG		tag;			/* unique identifier of lockable object */
145 146

	/* data */
147 148
	int			grantMask;		/* bitmask for lock types already granted */
	int			waitMask;		/* bitmask for lock types awaited */
B
Bruce Momjian 已提交
149
	SHM_QUEUE	lockHolders;	/* list of PROCLOCK objects assoc. with lock */
J
Jan Wieck 已提交
150
	PROC_QUEUE	waitProcs;		/* list of PGPROC objects waiting on lock */
B
Bruce Momjian 已提交
151 152
	int			requested[MAX_LOCKMODES];		/* counts of requested
												 * locks */
153
	int			nRequested;		/* total of requested[] array */
B
Bruce Momjian 已提交
154
	int			granted[MAX_LOCKMODES]; /* counts of granted locks */
155
	int			nGranted;		/* total of granted[] array */
156
} LOCK;
157

158
#define LOCK_LOCKMETHOD(lock) ((lock).tag.lockmethod)
159

160 161 162 163 164 165

/*
 * We may have several different transactions holding or awaiting locks
 * on the same lockable object.  We need to store some per-holder information
 * for each such holder (or would-be holder).
 *
B
Bruce Momjian 已提交
166 167
 * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
 * holder hashtable.  A PROCLOCKTAG value uniquely identifies a lock holder.
168 169
 *
 * There are two possible kinds of holder tags: a transaction (identified
J
Jan Wieck 已提交
170 171
 * both by the PGPROC of the backend running it, and the xact's own ID) and
 * a session (identified by backend PGPROC, with xid = InvalidTransactionId).
172 173 174 175
 *
 * Currently, session holders are used for user locks and for cross-xact
 * locks obtained for VACUUM.  We assume that a session lock never conflicts
 * with per-transaction locks obtained by the same backend.
176 177
 *
 * The holding[] array counts the granted locks (of each type) represented
B
Bruce Momjian 已提交
178
 * by this holder.	Note that there will be a holder object, possibly with
179 180 181
 * zero holding[], for any lock that the process is currently waiting on.
 * Otherwise, holder objects whose counts have gone to zero are recycled
 * as soon as convenient.
182
 *
B
Bruce Momjian 已提交
183 184
 * Each PROCLOCK object is linked into lists for both the associated LOCK object
 * and the owning PGPROC object.	Note that the PROCLOCK is entered into these
185
 * lists as soon as it is created, even if no lock has yet been granted.
J
Jan Wieck 已提交
186
 * A PGPROC that is waiting for a lock to be granted will also be linked into
187
 * the lock's waitProcs queue.
188
 */
B
Bruce Momjian 已提交
189
typedef struct PROCLOCKTAG
190 191
{
	SHMEM_OFFSET lock;			/* link to per-lockable-object information */
J
Jan Wieck 已提交
192
	SHMEM_OFFSET proc;			/* link to PGPROC of owning backend */
193
	TransactionId xid;			/* xact ID, or InvalidTransactionId */
B
Bruce Momjian 已提交
194
} PROCLOCKTAG;
195

B
Bruce Momjian 已提交
196
typedef struct PROCLOCK
197 198
{
	/* tag */
B
Bruce Momjian 已提交
199
	PROCLOCKTAG	tag;			/* unique identifier of holder object */
200 201

	/* data */
B
Bruce Momjian 已提交
202
	int			holding[MAX_LOCKMODES]; /* count of locks currently held */
203
	int			nHolding;		/* total of holding[] array */
204 205
	SHM_QUEUE	lockLink;		/* list link for lock's list of holders */
	SHM_QUEUE	procLink;		/* list link for process's list of holders */
B
Bruce Momjian 已提交
206
} PROCLOCK;
207

B
Bruce Momjian 已提交
208
#define PROCLOCK_LOCKMETHOD(holder) \
209 210 211
		(((LOCK *) MAKE_PTR((holder).tag.lock))->tag.lockmethod)


212 213 214
/*
 * function prototypes
 */
215
extern void InitLocks(void);
216
extern LOCKMETHODTABLE *GetLocksMethodTable(LOCK *lock);
B
Bruce Momjian 已提交
217
extern LOCKMETHOD LockMethodTableInit(char *tabName, LOCKMASK *conflictsP,
218
					int *prioP, int numModes, int maxBackends);
M
 
Marc G. Fournier 已提交
219 220
extern LOCKMETHOD LockMethodTableRename(LOCKMETHOD lockmethod);
extern bool LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag,
221
			TransactionId xid, LOCKMODE lockmode, bool dontWait);
M
 
Marc G. Fournier 已提交
222
extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
B
Bruce Momjian 已提交
223
			TransactionId xid, LOCKMODE lockmode);
J
Jan Wieck 已提交
224
extern bool LockReleaseAll(LOCKMETHOD lockmethod, PGPROC *proc,
B
Bruce Momjian 已提交
225
			   bool allxids, TransactionId xid);
226
extern int LockCheckConflicts(LOCKMETHODTABLE *lockMethodTable,
B
Bruce Momjian 已提交
227
				   LOCKMODE lockmode,
B
Bruce Momjian 已提交
228
				   LOCK *lock, PROCLOCK *holder, PGPROC *proc,
B
Bruce Momjian 已提交
229
				   int *myHolding);
B
Bruce Momjian 已提交
230
extern void GrantLock(LOCK *lock, PROCLOCK *holder, LOCKMODE lockmode);
J
Jan Wieck 已提交
231
extern void RemoveFromWaitQueue(PGPROC *proc);
232
extern int	LockShmemSize(int maxBackends);
J
Jan Wieck 已提交
233
extern bool DeadLockCheck(PGPROC *proc);
234
extern void InitDeadLockChecking(void);
235

236
#ifdef LOCK_DEBUG
237
extern void DumpLocks(void);
M
 
Marc G. Fournier 已提交
238
extern void DumpAllLocks(void);
239
#endif
240

241
#endif   /* LOCK_H */