00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _DB_LOCK_H_
00011 #define _DB_LOCK_H_
00012
00013 #define DB_LOCK_DEFAULT_N 1000
00014
00015
00016
00017
00018
00019
00020 #define DB_LOCK_INVALIDID 0
00021 #define DB_LOCK_MAXID 0x7fffffff
00022
00023
00024
00025
00026
00027 #define LOCK_INVALID INVALID_ROFF
00028 #define LOCK_ISSET(lock) ((lock).off != LOCK_INVALID)
00029 #define LOCK_INIT(lock) ((lock).off = LOCK_INVALID)
00030
00031
00032
00033
00034
00035 #define IS_WRITELOCK(m) \
00036 ((m) == DB_LOCK_WRITE || (m) == DB_LOCK_WWRITE || \
00037 (m) == DB_LOCK_IWRITE || (m) == DB_LOCK_IWR)
00038
00039
00040
00041
00042 typedef struct {
00043 u_int32_t tv_sec;
00044 u_int32_t tv_usec;
00045 } db_timeval_t;
00046
00047 #define LOCK_TIME_ISVALID(time) ((time)->tv_sec != 0)
00048 #define LOCK_SET_TIME_INVALID(time) ((time)->tv_sec = 0)
00049 #define LOCK_TIME_ISMAX(time) ((time)->tv_sec == UINT32_MAX)
00050 #define LOCK_SET_TIME_MAX(time) ((time)->tv_sec = UINT32_MAX)
00051 #define LOCK_TIME_EQUAL(t1, t2) \
00052 ((t1)->tv_sec == (t2)->tv_sec && (t1)->tv_usec == (t2)->tv_usec)
00053 #define LOCK_TIME_GREATER(t1, t2) \
00054 ((t1)->tv_sec > (t2)->tv_sec || \
00055 ((t1)->tv_sec == (t2)->tv_sec && (t1)->tv_usec > (t2)->tv_usec))
00056
00057
00058 #define LOCK_SYSTEM_LOCK(dbenv) \
00059 MUTEX_LOCK(dbenv, ((DB_LOCKREGION *)((DB_LOCKTAB *) \
00060 (dbenv)->lk_handle)->reginfo.primary)->mtx_region)
00061 #define LOCK_SYSTEM_UNLOCK(dbenv) \
00062 MUTEX_UNLOCK(dbenv, ((DB_LOCKREGION *)((DB_LOCKTAB *) \
00063 (dbenv)->lk_handle)->reginfo.primary)->mtx_region)
00064
00065
00066
00067
00068
00069 typedef struct __db_lockregion {
00070 db_mutex_t mtx_region;
00071
00072 u_int32_t need_dd;
00073 u_int32_t detect;
00074 db_timeval_t next_timeout;
00075
00076 SH_TAILQ_HEAD(__flock) free_locks;
00077
00078 SH_TAILQ_HEAD(__fobj) free_objs;
00079
00080 SH_TAILQ_HEAD(__flocker) free_lockers;
00081 SH_TAILQ_HEAD(__dobj) dd_objs;
00082 SH_TAILQ_HEAD(__lkrs) lockers;
00083
00084 db_timeout_t lk_timeout;
00085 db_timeout_t tx_timeout;
00086
00087 u_int32_t locker_t_size;
00088 u_int32_t object_t_size;
00089
00090 roff_t conf_off;
00091 roff_t obj_off;
00092 roff_t locker_off;
00093
00094 DB_LOCK_STAT stat;
00095 } DB_LOCKREGION;
00096
00097
00098
00099
00100
00101 typedef struct __sh_dbt {
00102 u_int32_t size;
00103 roff_t off;
00104 } SH_DBT;
00105
00106 #define SH_DBT_PTR(p) ((void *)(((u_int8_t *)(p)) + (p)->off))
00107
00108
00109
00110
00111 typedef struct __db_lockobj {
00112 SH_DBT lockobj;
00113 SH_TAILQ_ENTRY links;
00114 SH_TAILQ_ENTRY dd_links;
00115 SH_TAILQ_HEAD(__waitl) waiters;
00116 SH_TAILQ_HEAD(__holdl) holders;
00117
00118
00119
00120
00121 u_int8_t objdata[sizeof(struct __db_ilock)];
00122 } DB_LOCKOBJ;
00123
00124
00125
00126
00127 typedef struct __db_locker {
00128 u_int32_t id;
00129
00130 pid_t pid;
00131 db_threadid_t tid;
00132
00133 u_int32_t dd_id;
00134
00135 u_int32_t nlocks;
00136 u_int32_t nwrites;
00137
00138 roff_t master_locker;
00139 roff_t parent_locker;
00140 SH_LIST_HEAD(_child) child_locker;
00141
00142
00143 SH_LIST_ENTRY child_link;
00144
00145
00146 SH_TAILQ_ENTRY links;
00147 SH_TAILQ_ENTRY ulinks;
00148 SH_LIST_HEAD(_held) heldby;
00149 db_timeval_t lk_expire;
00150 db_timeval_t tx_expire;
00151 db_timeout_t lk_timeout;
00152
00153 #define DB_LOCKER_DELETED 0x0001
00154 #define DB_LOCKER_DIRTY 0x0002
00155 #define DB_LOCKER_INABORT 0x0004
00156 #define DB_LOCKER_TIMEOUT 0x0008
00157 u_int32_t flags;
00158 } DB_LOCKER;
00159
00160
00161
00162
00163
00164
00165 typedef struct __db_locktab {
00166 DB_ENV *dbenv;
00167 REGINFO reginfo;
00168 u_int8_t *conflicts;
00169 DB_HASHTAB *obj_tab;
00170 DB_HASHTAB *locker_tab;
00171 } DB_LOCKTAB;
00172
00173
00174
00175
00176
00177
00178 #define CONFLICTS(T, R, HELD, WANTED) \
00179 (T)->conflicts[((int)HELD) * (R)->stat.st_nmodes + ((int)WANTED)]
00180
00181 #define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1)
00182
00183 struct __db_lock {
00184
00185
00186
00187
00188 db_mutex_t mtx_lock;
00189
00190 u_int32_t holder;
00191 u_int32_t gen;
00192 SH_TAILQ_ENTRY links;
00193 SH_LIST_ENTRY locker_links;
00194 u_int32_t refcount;
00195 db_lockmode_t mode;
00196 roff_t obj;
00197 db_status_t status;
00198 };
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 #define DB_LOCK_DOALL 0x010000
00211 #define DB_LOCK_FREE 0x040000
00212 #define DB_LOCK_NOPROMOTE 0x080000
00213 #define DB_LOCK_UNLINK 0x100000
00214 #define DB_LOCK_NOREGION 0x200000
00215 #define DB_LOCK_NOWAITERS 0x400000
00216
00217
00218
00219
00220 #define OBJECT_LOCK(lt, reg, obj, ndx) \
00221 ndx = __lock_ohash(obj) % (reg)->object_t_size
00222 #define SHOBJECT_LOCK(lt, reg, shobj, ndx) \
00223 ndx = __lock_lhash(shobj) % (reg)->object_t_size
00224
00225
00226
00227
00228
00229
00230
00231 #define __lock_locker_hash(locker) (locker)
00232 #define LOCKER_LOCK(lt, reg, locker, ndx) \
00233 ndx = __lock_locker_hash(locker) % (reg)->locker_t_size;
00234
00235 #include "dbinc_auto/lock_ext.h"
00236 #endif