Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

lock.h

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: lock.h,v 12.7 2005/10/07 20:21:23 ubell Exp $
00008  */
00009 
00010 #ifndef _DB_LOCK_H_
00011 #define _DB_LOCK_H_
00012 
00013 #define DB_LOCK_DEFAULT_N       1000    /* Default # of locks in region. */
00014 
00015 /*
00016  * The locker id space is divided between the transaction manager and the lock
00017  * manager.  Lock IDs start at 1 and go to DB_LOCK_MAXID.  Txn IDs start at
00018  * DB_LOCK_MAXID + 1 and go up to TXN_MAXIMUM.
00019  */
00020 #define DB_LOCK_INVALIDID       0
00021 #define DB_LOCK_MAXID           0x7fffffff
00022 
00023 /*
00024  * Out of band value for a lock.  Locks contain an offset into a lock region,
00025  * so we use an invalid region offset to indicate an invalid or unset lock.
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  * Macro to identify a write lock for the purpose of counting locks
00033  * for the NUMWRITES option to deadlock detection.
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  * Lock timers.
00041  */
00042 typedef struct {
00043         u_int32_t       tv_sec;         /* Seconds. */
00044         u_int32_t       tv_usec;        /* Microseconds. */
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 /* Macros to lock/unlock the lock region as a whole. */
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  * DB_LOCKREGION --
00067  *      The lock shared region.
00068  */
00069 typedef struct __db_lockregion {
00070         db_mutex_t      mtx_region;     /* Region mutex. */
00071 
00072         u_int32_t       need_dd;        /* flag for deadlock detector */
00073         u_int32_t       detect;         /* run dd on every conflict */
00074         db_timeval_t    next_timeout;   /* next time to expire a lock */
00075                                         /* free lock header */
00076         SH_TAILQ_HEAD(__flock) free_locks;
00077                                         /* free obj header */
00078         SH_TAILQ_HEAD(__fobj) free_objs;
00079                                         /* free locker header */
00080         SH_TAILQ_HEAD(__flocker) free_lockers;
00081         SH_TAILQ_HEAD(__dobj) dd_objs;  /* objects with waiters */
00082         SH_TAILQ_HEAD(__lkrs) lockers;  /* list of lockers */
00083 
00084         db_timeout_t    lk_timeout;     /* timeout for locks. */
00085         db_timeout_t    tx_timeout;     /* timeout for txns. */
00086 
00087         u_int32_t       locker_t_size;  /* size of locker hash table */
00088         u_int32_t       object_t_size;  /* size of object hash table */
00089 
00090         roff_t          conf_off;       /* offset of conflicts array */
00091         roff_t          obj_off;        /* offset of object hash table */
00092         roff_t          locker_off;     /* offset of locker hash table */
00093 
00094         DB_LOCK_STAT    stat;           /* stats about locking. */
00095 } DB_LOCKREGION;
00096 
00097 /*
00098  * Since we will store DBTs in shared memory, we need the equivalent of a
00099  * DBT that will work in shared memory.
00100  */
00101 typedef struct __sh_dbt {
00102         u_int32_t size;                 /* Byte length. */
00103         roff_t    off;                  /* Region offset. */
00104 } SH_DBT;
00105 
00106 #define SH_DBT_PTR(p)   ((void *)(((u_int8_t *)(p)) + (p)->off))
00107 
00108 /*
00109  * Object structures;  these live in the object hash table.
00110  */
00111 typedef struct __db_lockobj {
00112         SH_DBT  lockobj;                /* Identifies object locked. */
00113         SH_TAILQ_ENTRY links;           /* Links for free list or hash list. */
00114         SH_TAILQ_ENTRY dd_links;        /* Links for dd list. */
00115         SH_TAILQ_HEAD(__waitl) waiters; /* List of waiting locks. */
00116         SH_TAILQ_HEAD(__holdl) holders; /* List of held locks. */
00117                                         /* Declare room in the object to hold
00118                                          * typical DB lock structures so that
00119                                          * we do not have to allocate them from
00120                                          * shalloc at run-time. */
00121         u_int8_t objdata[sizeof(struct __db_ilock)];
00122 } DB_LOCKOBJ;
00123 
00124 /*
00125  * Locker structures; these live in the locker hash table.
00126  */
00127 typedef struct __db_locker {
00128         u_int32_t id;                   /* Locker id. */
00129 
00130         pid_t pid;                      /* Process owning locker ID */
00131         db_threadid_t tid;              /* Thread owning locker ID */
00132 
00133         u_int32_t dd_id;                /* Deadlock detector id. */
00134 
00135         u_int32_t nlocks;               /* Number of locks held. */
00136         u_int32_t nwrites;              /* Number of write locks held. */
00137 
00138         roff_t  master_locker;          /* Locker of master transaction. */
00139         roff_t  parent_locker;          /* Parent of this child. */
00140         SH_LIST_HEAD(_child) child_locker;      /* List of descendant txns;
00141                                                    only used in a "master"
00142                                                    txn. */
00143         SH_LIST_ENTRY child_link;       /* Links transactions in the family;
00144                                            elements of the child_locker
00145                                            list. */
00146         SH_TAILQ_ENTRY links;           /* Links for free and hash list. */
00147         SH_TAILQ_ENTRY ulinks;          /* Links in-use list. */
00148         SH_LIST_HEAD(_held) heldby;     /* Locks held by this locker. */
00149         db_timeval_t    lk_expire;      /* When current lock expires. */
00150         db_timeval_t    tx_expire;      /* When this txn expires. */
00151         db_timeout_t    lk_timeout;     /* How long do we let locks live. */
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  * DB_LOCKTAB --
00162  *      The primary library lock data structure (i.e., the one referenced
00163  * by the environment, as opposed to the internal one laid out in the region.)
00164  */
00165 typedef struct __db_locktab {
00166         DB_ENV          *dbenv;         /* Environment. */
00167         REGINFO          reginfo;       /* Region information. */
00168         u_int8_t        *conflicts;     /* Pointer to conflict matrix. */
00169         DB_HASHTAB      *obj_tab;       /* Beginning of object hash table. */
00170         DB_HASHTAB      *locker_tab;    /* Beginning of locker hash table. */
00171 } DB_LOCKTAB;
00172 
00173 /*
00174  * Test for conflicts.
00175  *
00176  * Cast HELD and WANTED to ints, they are usually db_lockmode_t enums.
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          * Wait on mutex to wait on lock.  You reference your own mutex with
00186          * ID 0 and others reference your mutex with ID 1.
00187          */
00188         db_mutex_t      mtx_lock;
00189 
00190         u_int32_t       holder;         /* Who holds this lock. */
00191         u_int32_t       gen;            /* Generation count. */
00192         SH_TAILQ_ENTRY  links;          /* Free or holder/waiter list. */
00193         SH_LIST_ENTRY   locker_links;   /* List of locks held by a locker. */
00194         u_int32_t       refcount;       /* Reference count the lock. */
00195         db_lockmode_t   mode;           /* What sort of lock. */
00196         roff_t          obj;            /* Relative offset of object struct. */
00197         db_status_t     status;         /* Status of this lock. */
00198 };
00199 
00200 /*
00201  * Flag values for __lock_put_internal:
00202  * DB_LOCK_DOALL:     Unlock all references in this lock (instead of only 1).
00203  * DB_LOCK_FREE:      Free the lock (used in checklocker).
00204  * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks
00205  *                    (used by __lock_put_internal).
00206  * DB_LOCK_UNLINK:    Remove from the locker links (used in checklocker).
00207  * Make sure that these do not conflict with the interface flags because
00208  * we pass some of those around.
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  * Macros to get/release different types of mutexes.
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  * __lock_locker_hash --
00227  *      Hash function for entering lockers into the locker hash table.
00228  *      Since these are simply 32-bit unsigned integers at the moment,
00229  *      just return the locker value.
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 /* !_DB_LOCK_H_ */

Generated on Sun Dec 25 12:14:22 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2