lock.h

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: lock_8h-source.html,v 1.1 2008/06/08 10:19:54 sebdiaz Exp $
00008  */
00009 
00010 #ifndef DB_LOCK_DEFAULT_N
00011 #define DB_LOCK_DEFAULT_N       1000    /* Default # of locks in region. */
00012 #endif
00013 
00014 /*
00015  * Out of band value for a lock.  Locks contain an offset into a lock region,
00016  * so we use an invalid region offset to indicate an invalid or unset lock.
00017  */
00018 #define LOCK_INVALID    INVALID_ROFF
00019 
00020 /*
00021  * The locker id space is divided between the transaction manager and the lock
00022  * manager.  Lock IDs start at 0 and go to DB_LOCK_MAXID.  Txn IDs start at
00023  * DB_LOCK_MAXID + 1 and go up to TXN_INVALID.
00024  */
00025 #define DB_LOCK_MAXID           0x7fffffff
00026 
00027 /*
00028  * DB_LOCKREGION --
00029  *      The lock shared region.
00030  */
00031 typedef struct __db_lockregion {
00032         u_int32_t       id;             /* unique id generator */
00033         u_int32_t       need_dd;        /* flag for deadlock detector */
00034         u_int32_t       detect;         /* run dd on every conflict */
00035                                         /* free lock header */
00036         SH_TAILQ_HEAD(__flock) free_locks;
00037                                         /* free obj header */
00038         SH_TAILQ_HEAD(__fobj) free_objs;
00039                                         /* free locker header */
00040         SH_TAILQ_HEAD(__flocker) free_lockers;
00041         SH_TAILQ_HEAD(__dobj) dd_objs;  /* objects with waiters */
00042         u_int32_t       maxlocks;       /* maximum number of locks in table */
00043         u_int32_t       table_size;     /* size of hash table */
00044         u_int32_t       nmodes;         /* number of lock modes */
00045         u_int32_t       nlockers;       /* number of lockers */
00046         u_int32_t       maxnlockers;    /* maximum number of lockers */
00047         roff_t          conf_off;       /* offset of conflicts array */
00048         roff_t          obj_off;        /* offset of object hash table */
00049         roff_t          osynch_off;     /* offset of the object mutex table */
00050         roff_t          locker_off;     /* offset of locker hash table */
00051         roff_t          lsynch_off;     /* offset of the locker mutex table */
00052         u_int32_t       nconflicts;     /* number of lock conflicts */
00053         u_int32_t       nrequests;      /* number of lock gets */
00054         u_int32_t       nreleases;      /* number of lock puts */
00055         u_int32_t       nnowaits;       /* number of lock requests that would
00056                                            have waited without nowait */
00057         u_int32_t       ndeadlocks;     /* number of deadlocks */
00058 } DB_LOCKREGION;
00059 
00060 /*
00061  * Since we will store DBTs in shared memory, we need the equivalent of a
00062  * DBT that will work in shared memory.
00063  */
00064 typedef struct __sh_dbt {
00065         u_int32_t size;                 /* Byte length. */
00066         ssize_t   off;                  /* Region offset. */
00067 } SH_DBT;
00068 
00069 #define SH_DBT_PTR(p)   ((void *)(((u_int8_t *)(p)) + (p)->off))
00070 
00071 /*
00072  * Object structures;  these live in the object hash table.
00073  */
00074 typedef struct __db_lockobj {
00075         SH_DBT  lockobj;                /* Identifies object locked. */
00076         SH_TAILQ_ENTRY links;           /* Links for free list or hash list. */
00077         SH_TAILQ_ENTRY dd_links;        /* Links for dd list. */
00078         SH_TAILQ_HEAD(__wait) waiters;  /* List of waiting locks. */
00079         SH_TAILQ_HEAD(__hold) holders;  /* List of held locks. */
00080                                         /* Declare room in the object to hold
00081                                          * typical DB lock structures so that
00082                                          * we do not have to allocate them from
00083                                          * shalloc at run-time. */
00084         u_int8_t objdata[sizeof(struct __db_ilock)];
00085 } DB_LOCKOBJ;
00086 
00087 /*
00088  * Locker structures; these live in the locker hash table.
00089  */
00090 typedef struct __db_locker {
00091         u_int32_t id;                   /* Locker id. */
00092         u_int32_t dd_id;                /* Deadlock detector id. */
00093         size_t master_locker;           /* Locker of master transaction. */
00094         size_t parent_locker;           /* Parent of this child. */
00095         SH_LIST_HEAD(_child) child_locker;      /* List of descendant txns;
00096                                                    only used in a "master"
00097                                                    txn. */
00098         SH_LIST_ENTRY child_link;       /* Links transactions in the family;
00099                                            elements of the child_locker
00100                                            list. */
00101         SH_TAILQ_ENTRY links;           /* Links for free list. */
00102         SH_LIST_HEAD(_held) heldby;     /* Locks held by this locker. */
00103 
00104 #define DB_LOCKER_DELETED       0x0001
00105         u_int32_t flags;
00106 } DB_LOCKER;
00107 
00108 /*
00109  * Lockers can be freed if they are not part of a transaction family.
00110  * Members of a family either point at the master transaction or are
00111  * the master transaction and have children lockers.
00112  */
00113 #define LOCKER_FREEABLE(lp)                                             \
00114     ((lp)->master_locker == TXN_INVALID_ID &&                           \
00115     SH_LIST_FIRST(&(lp)->child_locker, __db_locker) == NULL)
00116 
00117 /*
00118  * DB_LOCKTAB --
00119  *      The primary library lock data structure (i.e., the one referenced
00120  * by the environment, as opposed to the internal one laid out in the region.)
00121  */
00122 typedef struct __db_locktab {
00123         DB_ENV          *dbenv;         /* Environment. */
00124         REGINFO          reginfo;       /* Region information. */
00125         u_int8_t        *conflicts;     /* Pointer to conflict matrix. */
00126         DB_HASHTAB      *obj_tab;       /* Beginning of object hash table. */
00127         DB_HASHTAB      *locker_tab;    /* Beginning of locker hash table. */
00128 } DB_LOCKTAB;
00129 
00130 /* Test for conflicts. */
00131 #define CONFLICTS(T, R, HELD, WANTED) \
00132         (T)->conflicts[(HELD) * (R)->nmodes + (WANTED)]
00133 
00134 #define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1)
00135 
00136 struct __db_lock {
00137         /*
00138          * Wait on mutex to wait on lock.  You reference your own mutex with
00139          * ID 0 and others reference your mutex with ID 1.
00140          */
00141         MUTEX           mutex;
00142 
00143         u_int32_t       holder;         /* Who holds this lock. */
00144         u_int32_t       gen;            /* Generation count. */
00145         SH_TAILQ_ENTRY  links;          /* Free or holder/waiter list. */
00146         SH_LIST_ENTRY   locker_links;   /* List of locks held by a locker. */
00147         u_int32_t       refcount;       /* Reference count the lock. */
00148         db_lockmode_t   mode;           /* What sort of lock. */
00149         ssize_t         obj;            /* Relative offset of object struct. */
00150         db_status_t     status;         /* Status of this lock. */
00151 };
00152 
00153 /*
00154  * Flag values for __lock_put_internal:
00155  * DB_LOCK_DOALL:     Unlock all references in this lock (instead of only 1).
00156  * DB_LOCK_FREE:      Free the lock (used in checklocker).
00157  * DB_LOCK_IGNOREDEL: Remove from the locker hash table even if already
00158                       deleted (used in checklocker).
00159  * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks
00160  *                    (used by __lock_put_internal).
00161  * DB_LOCK_UNLINK:    Remove from the locker links (used in checklocker).
00162  */
00163 #define DB_LOCK_DOALL           0x001
00164 #define DB_LOCK_FREE            0x002
00165 #define DB_LOCK_IGNOREDEL       0x004
00166 #define DB_LOCK_NOPROMOTE       0x008
00167 #define DB_LOCK_UNLINK          0x010
00168 
00169 /*
00170  * Macros to get/release different types of mutexes.
00171  */
00172 #define OBJECT_LOOKUP(lt, ndx, dbt, sh_obj)                             \
00173         HASHLOOKUP((lt)->objtab,                                        \
00174             ndx, __db_lockobj, links, dbt, sh_obj, CDB___lock_cmp);
00175 
00176 #define OBJECT_LOCK(lt, reg, obj, ndx)                                  \
00177         ndx = CDB___lock_ohash(obj) % (reg)->table_size
00178 #define SHOBJECT_LOCK(lt, reg, shobj, ndx)                              \
00179         ndx = CDB___lock_lhash(shobj) % (reg)->table_size
00180 #define OBJECT_UNLOCK(lt, ndx)
00181 
00182 #define LOCKER_LOOKUP(lt, ndx, locker, sh_locker)                       \
00183         HASHLOOKUP((lt)->lockertab,                                     \
00184             ndx, __db_locker, links, locker, sh_locker, CDB___lock_locker_cmp);
00185 
00186 #define LOCKREGION(dbenv, lt)  R_LOCK((dbenv), &(lt)->reginfo)
00187 #define UNLOCKREGION(dbenv, lt)  R_UNLOCK((dbenv), &(lt)->reginfo)
00188 #include "lock_ext.h"

Generated on Sun Jun 8 10:56:38 2008 for GNUmifluz by  doxygen 1.5.5