aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/lock.h
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
committerMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
commitd31084e9d1118b25fd16580d9d8c2924b5740dff (patch)
tree3179e66307d54df9c7b966543550e601eb55e668 /src/backend/storage/lock.h
downloadpostgresql-PG95-1_01.tar.gz
postgresql-PG95-1_01.zip
Postgres95 1.01 Distribution - Virgin SourcesPG95-1_01
Diffstat (limited to 'src/backend/storage/lock.h')
-rw-r--r--src/backend/storage/lock.h218
1 files changed, 218 insertions, 0 deletions
diff --git a/src/backend/storage/lock.h b/src/backend/storage/lock.h
new file mode 100644
index 00000000000..df490e76512
--- /dev/null
+++ b/src/backend/storage/lock.h
@@ -0,0 +1,218 @@
+/*-------------------------------------------------------------------------
+ *
+ * lock.h--
+ *
+ *
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: lock.h,v 1.1.1.1 1996/07/09 06:21:53 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LOCK_H_
+#define LOCK_H_
+
+#include "postgres.h"
+#include "storage/itemptr.h"
+#include "storage/shmem.h"
+#include "storage/spin.h"
+#include "storage/backendid.h"
+#include "utils/hsearch.h"
+
+extern SPINLOCK LockMgrLock;
+typedef int MASK;
+
+#define INIT_TABLE_SIZE 100
+#define MAX_TABLE_SIZE 1000
+
+
+/* ----------------------
+ * The following defines are used to estimate how much shared
+ * memory the lock manager is going to require.
+ *
+ * NBACKENDS - The number of concurrently running backends
+ * NLOCKS_PER_XACT - The number of unique locks acquired in a transaction
+ * NLOCKENTS - The maximum number of lock entries in the lock table.
+ * ----------------------
+ */
+#define NBACKENDS 50
+#define NLOCKS_PER_XACT 40
+#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
+
+typedef int LOCK_TYPE;
+typedef int LOCKT;
+typedef int LockTableId;
+
+/* MAX_LOCKTYPES cannot be larger than the bits in MASK */
+#define MAX_LOCKTYPES 6
+
+/*
+ * MAX_TABLES corresponds to the number of spin locks allocated in
+ * CreateSpinLocks() or the number of shared memory locations allocated
+ * for lock table spin locks in the case of machines with TAS instructions.
+ */
+#define MAX_TABLES 2
+
+#define INVALID_TABLEID 0
+
+/*typedef struct LOCK LOCK; */
+
+
+typedef struct ltag {
+ Oid relId;
+ Oid dbId;
+ ItemPointerData tupleId;
+} LOCKTAG;
+
+#define TAGSIZE (sizeof(LOCKTAG))
+
+/* This is the control structure for a lock table. It
+ * lives in shared memory:
+ *
+ * tableID -- the handle used by the lock table's clients to
+ * refer to the table.
+ *
+ * nLockTypes -- number of lock types (READ,WRITE,etc) that
+ * are defined on this lock table
+ *
+ * conflictTab -- this is an array of bitmasks showing lock
+ * type conflicts. conflictTab[i] is a mask with the j-th bit
+ * turned on if lock types i and j conflict.
+ *
+ * prio -- each locktype has a priority, so, for example, waiting
+ * writers can be given priority over readers (to avoid
+ * starvation).
+ *
+ * masterlock -- synchronizes access to the table
+ *
+ */
+typedef struct lockctl {
+ LockTableId tableId;
+ int nLockTypes;
+ int conflictTab[MAX_LOCKTYPES];
+ int prio[MAX_LOCKTYPES];
+ SPINLOCK masterLock;
+} LOCKCTL;
+
+/*
+ * lockHash -- hash table on lock Ids,
+ * xidHash -- hash on xid and lockId in case
+ * multiple processes are holding the lock
+ * ctl - control structure described above.
+ */
+typedef struct ltable {
+ HTAB *lockHash;
+ HTAB *xidHash;
+ LOCKCTL *ctl;
+} LOCKTAB;
+
+/* -----------------------
+ * A transaction never conflicts with its own locks. Hence, if
+ * multiple transactions hold non-conflicting locks on the same
+ * data, private per-transaction information must be stored in the
+ * XID table. The tag is XID + shared memory lock address so that
+ * all locks can use the same XID table. The private information
+ * we store is the number of locks of each type (holders) and the
+ * total number of locks (nHolding) held by the transaction.
+ *
+ * NOTE: --
+ * There were some problems with the fact that currently TransactionIdData
+ * is a 5 byte entity and compilers long word aligning of structure fields.
+ * If the 3 byte padding is put in front of the actual xid data then the
+ * hash function (which uses XID_TAGSIZE when deciding how many bytes of a
+ * struct to look at for the key) might only see the last two bytes of the xid.
+ *
+ * Clearly this is not good since its likely that these bytes will be the
+ * same for many transactions and hence they will share the same entry in
+ * hash table causing the entry to be corrupted. For this long-winded
+ * reason I have put the tag in a struct of its own to ensure that the
+ * XID_TAGSIZE is computed correctly. It used to be sizeof (SHMEM_OFFSET) +
+ * sizeof(TransactionIdData) which != sizeof(XIDTAG).
+ *
+ * Finally since the hash function will now look at all 12 bytes of the tag
+ * the padding bytes MUST be zero'd before use in hash_search() as they
+ * will have random values otherwise. Jeff 22 July 1991.
+ * -----------------------
+ */
+
+typedef struct XIDTAG {
+ SHMEM_OFFSET lock;
+ int pid;
+ TransactionId xid;
+} XIDTAG;
+
+typedef struct XIDLookupEnt {
+ /* tag */
+ XIDTAG tag;
+
+ /* data */
+ int holders[MAX_LOCKTYPES];
+ int nHolding;
+ SHM_QUEUE queue;
+} XIDLookupEnt;
+
+#define XID_TAGSIZE (sizeof(XIDTAG))
+
+/* originally in procq.h */
+typedef struct procQueue {
+ SHM_QUEUE links;
+ int size;
+} PROC_QUEUE;
+
+
+/*
+ * lock information:
+ *
+ * tag -- uniquely identifies the object being locked
+ * mask -- union of the conflict masks of all lock types
+ * currently held on this object.
+ * waitProcs -- queue of processes waiting for this lock
+ * holders -- count of each lock type currently held on the
+ * lock.
+ * nHolding -- total locks of all types.
+ */
+typedef struct Lock {
+ /* hash key */
+ LOCKTAG tag;
+
+ /* data */
+ int mask;
+ PROC_QUEUE waitProcs;
+ int holders[MAX_LOCKTYPES];
+ int nHolding;
+ int activeHolders[MAX_LOCKTYPES];
+ int nActive;
+} LOCK;
+
+#define LockGetLock_nHolders(l) l->nHolders
+
+#define LockDecrWaitHolders(lock, lockt) \
+ lock->nHolding--; \
+ lock->holders[lockt]--
+
+#define LockLockTable() SpinAcquire(LockMgrLock);
+#define UnlockLockTable() SpinRelease(LockMgrLock);
+
+extern SPINLOCK LockMgrLock;
+
+/*
+ * function prototypes
+ */
+extern void InitLocks(void);
+extern void LockDisable(int status);
+extern LockTableId LockTabInit(char *tabName, MASK *conflictsP, int *prioP,
+ int ntypes);
+extern LockTableId LockTabRename(LockTableId tableId);
+extern bool LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
+extern int LockResolveConflicts(LOCKTAB *ltable, LOCK *lock, LOCKT lockt,
+ TransactionId xid);
+extern int WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock,
+ LOCKT lockt);
+extern bool LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
+extern void GrantLock(LOCK *lock, LOCKT lockt);
+extern bool LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue);
+extern int LockShmemSize(void);
+extern bool LockingDisabled(void);
+
+#endif /* LOCK_H */