2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 1996-2002
5
* Sleepycat Software. All rights reserved.
13
#define DB_LOCK_DEFAULT_N 1000 /* Default # of locks in region. */
16
* The locker id space is divided between the transaction manager and the lock
17
* manager. Lock IDs start at 1 and go to DB_LOCK_MAXID. Txn IDs start at
18
* DB_LOCK_MAXID + 1 and go up to TXN_MAXIMUM.
20
#define DB_LOCK_INVALIDID 0
21
#define DB_LOCK_MAXID 0x7fffffff
24
* Out of band value for a lock. Locks contain an offset into a lock region,
25
* so we use an invalid region offset to indicate an invalid or unset lock.
27
#define LOCK_INVALID INVALID_ROFF
28
#define LOCK_ISSET(lock) ((lock).off != LOCK_INVALID)
29
#define LOCK_INIT(lock) ((lock).off = LOCK_INVALID)
32
* Macro to identify a write lock for the purpose of counting locks
33
* for the NUMWRITES option to deadlock detection.
35
#define IS_WRITELOCK(m) \
36
((m) == DB_LOCK_WRITE || (m) == DB_LOCK_IWRITE || (m) == DB_LOCK_IWR)
42
u_int32_t tv_sec; /* Seconds. */
43
u_int32_t tv_usec; /* Microseconds. */
46
#define LOCK_TIME_ISVALID(time) ((time)->tv_sec != 0)
47
#define LOCK_SET_TIME_INVALID(time) ((time)->tv_sec = 0)
48
#define LOCK_TIME_EQUAL(t1, t2) \
49
((t1)->tv_sec == (t2)->tv_sec && (t1)->tv_usec == (t2)->tv_usec)
53
* The lock shared region.
55
typedef struct __db_lockregion {
56
u_int32_t need_dd; /* flag for deadlock detector */
57
u_int32_t detect; /* run dd on every conflict */
58
/* free lock header */
59
SH_TAILQ_HEAD(__flock) free_locks;
61
SH_TAILQ_HEAD(__fobj) free_objs;
62
/* free locker header */
63
SH_TAILQ_HEAD(__flocker) free_lockers;
64
SH_TAILQ_HEAD(__dobj) dd_objs; /* objects with waiters */
65
SH_TAILQ_HEAD(__lkrs) lockers; /* list of lockers */
67
db_timeout_t lk_timeout; /* timeout for locks. */
68
db_timeout_t tx_timeout; /* timeout for txns. */
70
u_int32_t locker_t_size; /* size of locker hash table */
71
u_int32_t object_t_size; /* size of object hash table */
73
roff_t conf_off; /* offset of conflicts array */
74
roff_t obj_off; /* offset of object hash table */
75
roff_t osynch_off; /* offset of the object mutex table */
76
roff_t locker_off; /* offset of locker hash table */
77
roff_t lsynch_off; /* offset of the locker mutex table */
79
DB_LOCK_STAT stat; /* stats about locking. */
81
#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
82
roff_t maint_off; /* offset of region maintenance info */
87
* Since we will store DBTs in shared memory, we need the equivalent of a
88
* DBT that will work in shared memory.
90
typedef struct __sh_dbt {
91
u_int32_t size; /* Byte length. */
92
ssize_t off; /* Region offset. */
95
#define SH_DBT_PTR(p) ((void *)(((u_int8_t *)(p)) + (p)->off))
98
* Object structures; these live in the object hash table.
100
typedef struct __db_lockobj {
101
SH_DBT lockobj; /* Identifies object locked. */
102
SH_TAILQ_ENTRY links; /* Links for free list or hash list. */
103
SH_TAILQ_ENTRY dd_links; /* Links for dd list. */
104
SH_TAILQ_HEAD(__wait) waiters; /* List of waiting locks. */
105
SH_TAILQ_HEAD(__hold) holders; /* List of held locks. */
106
/* Declare room in the object to hold
107
* typical DB lock structures so that
108
* we do not have to allocate them from
109
* shalloc at run-time. */
110
u_int8_t objdata[sizeof(struct __db_ilock)];
114
* Locker structures; these live in the locker hash table.
116
typedef struct __db_locker {
117
u_int32_t id; /* Locker id. */
118
u_int32_t dd_id; /* Deadlock detector id. */
119
u_int32_t nlocks; /* Number of locks held. */
120
u_int32_t nwrites; /* Number of write locks held. */
121
size_t master_locker; /* Locker of master transaction. */
122
size_t parent_locker; /* Parent of this child. */
123
SH_LIST_HEAD(_child) child_locker; /* List of descendant txns;
124
only used in a "master"
126
SH_LIST_ENTRY child_link; /* Links transactions in the family;
127
elements of the child_locker
129
SH_TAILQ_ENTRY links; /* Links for free and hash list. */
130
SH_TAILQ_ENTRY ulinks; /* Links in-use list. */
131
SH_LIST_HEAD(_held) heldby; /* Locks held by this locker. */
132
db_timeval_t lk_expire; /* When current lock expires. */
133
db_timeval_t tx_expire; /* When this txn expires. */
134
db_timeout_t lk_timeout; /* How long do we let locks live. */
136
#define DB_LOCKER_DELETED 0x0001
137
#define DB_LOCKER_DIRTY 0x0002
138
#define DB_LOCKER_INABORT 0x0004
139
#define DB_LOCKER_TIMEOUT 0x0008
145
* The primary library lock data structure (i.e., the one referenced
146
* by the environment, as opposed to the internal one laid out in the region.)
148
typedef struct __db_locktab {
149
DB_ENV *dbenv; /* Environment. */
150
REGINFO reginfo; /* Region information. */
151
u_int8_t *conflicts; /* Pointer to conflict matrix. */
152
DB_HASHTAB *obj_tab; /* Beginning of object hash table. */
153
DB_HASHTAB *locker_tab; /* Beginning of locker hash table. */
156
/* Test for conflicts. */
157
#define CONFLICTS(T, R, HELD, WANTED) \
158
(T)->conflicts[(HELD) * (R)->stat.st_nmodes + (WANTED)]
160
#define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1)
164
* Wait on mutex to wait on lock. You reference your own mutex with
165
* ID 0 and others reference your mutex with ID 1.
169
u_int32_t holder; /* Who holds this lock. */
170
u_int32_t gen; /* Generation count. */
171
SH_TAILQ_ENTRY links; /* Free or holder/waiter list. */
172
SH_LIST_ENTRY locker_links; /* List of locks held by a locker. */
173
u_int32_t refcount; /* Reference count the lock. */
174
db_lockmode_t mode; /* What sort of lock. */
175
ssize_t obj; /* Relative offset of object struct. */
176
db_status_t status; /* Status of this lock. */
180
* Flag values for __lock_put_internal:
181
* DB_LOCK_DOALL: Unlock all references in this lock (instead of only 1).
182
* DB_LOCK_FREE: Free the lock (used in checklocker).
183
* DB_LOCK_IGNOREDEL: Remove from the locker hash table even if already
184
deleted (used in checklocker).
185
* DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks
186
* (used by __lock_put_internal).
187
* DB_LOCK_UNLINK: Remove from the locker links (used in checklocker).
188
* Make sure that these do not conflict with the interface flags because
189
* we pass some of those around (i.e., DB_LOCK_REMOVE).
191
#define DB_LOCK_DOALL 0x010000
192
#define DB_LOCK_FREE 0x020000
193
#define DB_LOCK_IGNOREDEL 0x040000
194
#define DB_LOCK_NOPROMOTE 0x080000
195
#define DB_LOCK_UNLINK 0x100000
196
#define DB_LOCK_NOWAITERS 0x200000
199
* Macros to get/release different types of mutexes.
201
#define OBJECT_LOCK(lt, reg, obj, ndx) \
202
ndx = __lock_ohash(obj) % (reg)->object_t_size
203
#define SHOBJECT_LOCK(lt, reg, shobj, ndx) \
204
ndx = __lock_lhash(shobj) % (reg)->object_t_size
205
#define LOCKER_LOCK(lt, reg, locker, ndx) \
206
ndx = __lock_locker_hash(locker) % (reg)->locker_t_size;
208
#define LOCKREGION(dbenv, lt) R_LOCK((dbenv), &(lt)->reginfo)
209
#define UNLOCKREGION(dbenv, lt) R_UNLOCK((dbenv), &(lt)->reginfo)
211
#include "dbinc_auto/lock_ext.h"
212
#endif /* !_DB_LOCK_H_ */