region.h
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  *
  7.  * $Id: region.h,v 11.13 2000/11/15 19:25:37 sue Exp $
  8.  */
  9. /*
  10.  * The DB environment consists of some number of "regions", which are described
  11.  * by the following four structures:
  12.  *
  13.  * REGENV    -- shared information about the environment
  14.  * REGENV_REF -- file describing system memory version of REGENV
  15.  * REGION    -- shared information about a single region
  16.  * REGINFO    -- per-process information about a REGION
  17.  *
  18.  * There are three types of memory that hold regions:
  19.  * per-process heap (malloc)
  20.  * file mapped into memory (mmap, MapViewOfFile)
  21.  * system memory (shmget, CreateFileMapping)
  22.  *
  23.  * If the regions are private to a process, they're in malloc.  If they're
  24.  * public, they're in file mapped memory, or, optionally, in system memory.
  25.  * Regions in the filesystem are named "__db.001", "__db.002" and so on.  If
  26.  * we're not using a private environment allocated using malloc(3), the file
  27.  * "__db.001" will always exist, as we use it to synchronize on the regions,
  28.  * whether they exist in file mapped memory or system memory.
  29.  *
  30.  * The file "__db.001" contains a REGENV structure and a linked list of some
  31.  * number of REGION structures.  Each of the REGION structures describes and
  32.  * locks one of the underlying shared regions used by DB.
  33.  *
  34.  * __db.001
  35.  * +---------+
  36.  * |REGENV  |
  37.  * +---------+   +----------+
  38.  * |REGION   |-> | __db.002 |
  39.  * |   |   +----------+
  40.  * +---------+   +----------+
  41.  * |REGION   |-> | __db.003 |
  42.  * |   |   +----------+
  43.  * +---------+   +----------+
  44.  * |REGION   |-> | __db.004 |
  45.  * |   |   +----------+
  46.  * +---------+
  47.  *
  48.  * The only tricky part about manipulating the regions is correctly creating
  49.  * or joining the REGENV file, i.e., __db.001.  We have to be absolutely sure
  50.  * that only one process creates it, and that everyone else joins it without
  51.  * seeing inconsistent data.  Once that region is created, we can use normal
  52.  * shared locking procedures to do mutal exclusion for all other regions.
  53.  *
  54.  * One of the REGION structures in the main environment region describes the
  55.  * environment region itself.
  56.  *
  57.  * To lock a region, locate the REGION structure that describes it and acquire
  58.  * the region's mutex.  There is one exception to this rule -- the lock for the
  59.  * environment region itself is in the REGENV structure, and not in the REGION
  60.  * that describes the environment region.  That's so that we can acquire a lock
  61.  * without walking linked lists that could potentially change underneath us.
  62.  * The REGION will not be moved or removed during the life of the region, and
  63.  * so long-lived references to it can be held by the process.
  64.  *
  65.  * All requests to create or join a region return a REGINFO structure, which
  66.  * is held by the caller and used to open and subsequently close the reference
  67.  * to the region.  The REGINFO structure contains the per-process information
  68.  * that we need to access the region.
  69.  *
  70.  * The one remaining complication.  If the regions (including the environment
  71.  * region) live in system memory, and the system memory isn't "named" somehow
  72.  * in the filesystem name space, we need some way of finding it.  Do this by
  73.  * by writing the REGENV_REF structure into the "__db.001" file.  When we find
  74.  * a __db.001 file that is too small to be a real, on-disk environment, we use
  75.  * the information it contains to redirect to the real "__db.001" file/memory.
  76.  * This currently only happens when the REGENV file is in shared system memory.
  77.  *
  78.  * Although DB does not currently grow regions when they run out of memory, it
  79.  * would be possible to do so.  To grow a region, allocate a new region of the
  80.  * appropriate size, then copy the old region over it and insert the additional
  81.  * space into the already existing shalloc arena.  Callers may have to fix up
  82.  * local references, but that should be easy to do.  This failed in historic
  83.  * versions of DB because the region lock lived in the mapped memory, and when
  84.  * it was unmapped and remapped (or copied), threads could lose track of it.
  85.  * Once we moved that lock into a region that is never unmapped, growing should
  86.  * work.  That all said, current versions of DB don't implement region grow
  87.  * because some systems don't support mutex copying, e.g., from OSF1 V4.0:
  88.  *
  89.  *      The address of an msemaphore structure may be significant.  If the
  90.  * msemaphore structure contains any value copied from an msemaphore
  91.  * structure at a different address, the result is undefined.
  92.  */
  93. #if defined(__cplusplus)
  94. extern "C" {
  95. #endif
  96. #define DB_REGION_FMT "__db.%03d" /* Region file name format. */
  97. #define DB_REGION_NAME_NUM 5 /* First digit offset in file names. */
  98. #define DB_REGION_NAME_LENGTH 8 /* Length of file names. */
  99. #define DB_REGION_ENV "__db.001" /* Primary environment name. */
  100. #define INVALID_REGION_ID 0 /* Out-of-band region ID. */
  101. #define REGION_ID_ENV 1 /* Primary environment ID. */
  102. typedef enum {
  103. INVALID_REGION_TYPE=0, /* Region type. */
  104. REGION_TYPE_ENV,
  105. REGION_TYPE_LOCK,
  106. REGION_TYPE_LOG,
  107. REGION_TYPE_MPOOL,
  108. REGION_TYPE_MUTEX,
  109. REGION_TYPE_TXN } reg_type;
  110. #define INVALID_REGION_SEGID -1 /* Segment IDs are either shmget(2) or
  111.  * Win16 segment identifiers.  They are
  112.  * both stored in a "long", and we need
  113.  * an out-of-band value.
  114.  */
  115. /*
  116.  * Nothing can live at region offset 0, because, in all cases, that's where
  117.  * we store *something*.  Lots of code needs an out-of-band value for region
  118.  * offsets, so we use 0.
  119.  */
  120. #define INVALID_ROFF 0
  121. /* Reference describing system memory version of REGENV. */
  122. typedef struct __db_reg_env_ref {
  123. roff_t    size; /* Region size. */
  124. long    segid; /* UNIX shmget(2) ID. */
  125. } REGENV_REF;
  126. /* Per-environment region information. */
  127. typedef struct __db_reg_env {
  128. /*
  129.  * !!!
  130.  * The mutex must be the first entry in the structure to guarantee
  131.  * correct alignment.
  132.  */
  133. MUTEX      mutex; /* Environment mutex. */
  134. /*
  135.  * !!!
  136.  * Note, the magic and panic fields are NOT protected by any mutex,
  137.  * and for this reason cannot be anything more complicated than a
  138.  * zero/non-zero value.
  139.  *
  140.  * !!!
  141.  * The valid region magic number must appear at the same byte offset
  142.  * in both the environment and each shared region, as Windows/95 uses
  143.  * it to determine if the memory has been zeroed since it was last used.
  144.  */
  145. u_int32_t  magic; /* Valid region magic number. */
  146. int    panic; /* Environment is dead. */
  147. int    majver; /* Major DB version number. */
  148. int    minver; /* Minor DB version number. */
  149. int    patch; /* Patch DB version number. */
  150. u_int32_t  init_flags; /* Flags the env was initialized with.*/
  151. /* List of regions. */
  152. SH_LIST_HEAD(__db_regionh) regionq;
  153. u_int32_t  refcnt; /* References to the environment. */
  154. size_t    pad; /* Guarantee that following memory is
  155.  * size_t aligned.  This is necessary
  156.  * because we're going to store the
  157.  * allocation region information there.
  158.  */
  159. } REGENV;
  160. /* Per-region shared region information. */
  161. typedef struct __db_region {
  162. /*
  163.  * !!!
  164.  * The mutex must be the first entry in the structure to guarantee
  165.  * correct alignment.
  166.  */
  167. MUTEX    mutex; /* Region mutex. */
  168. /*
  169.  * !!!
  170.  * The valid region magic number must appear at the same byte offset
  171.  * in both the environment and each shared region, as Windows/95 uses
  172.  * it to determine if the memory has been zeroed since it was last used.
  173.  */
  174. u_int32_t  magic;
  175. SH_LIST_ENTRY q; /* Linked list of REGIONs. */
  176. reg_type   type; /* Region type. */
  177. u_int32_t  id; /* Region id. */
  178. roff_t    size; /* Region size in bytes. */
  179. roff_t    primary; /* Primary data structure offset. */
  180. long    segid; /* UNIX shmget(2), Win16 segment ID. */
  181. } REGION;
  182. /*
  183.  * Per-process/per-attachment information about a single region.
  184.  */
  185. struct __db_reginfo_t { /* __db_r_attach IN parameters. */
  186. reg_type    type; /* Region type. */
  187. u_int32_t   id; /* Region id. */
  188. int     mode; /* File creation mode. */
  189. /* __db_r_attach OUT parameters. */
  190. REGION    *rp; /* Shared region. */
  191. char    *name; /* Region file name. */
  192. void    *addr; /* Region allocation address. */
  193. void    *primary; /* Primary data structure address. */
  194. void    *wnt_handle; /* Win/NT HANDLE. */
  195. #define REGION_CREATE 0x01 /* Caller created region. */
  196. #define REGION_CREATE_OK 0x02 /* Caller willing to create region. */
  197. #define REGION_JOIN_OK 0x04 /* Caller is looking for a match. */
  198. u_int32_t   flags;
  199. };
  200. /*
  201.  * Mutex maintenance information each subsystem region must keep track
  202.  * of to manage resources adequately.
  203.  */
  204. typedef struct __db_regmaint_stat_t {
  205. u_int32_t st_hint_hit;
  206. u_int32_t st_hint_miss;
  207. u_int32_t st_records;
  208. u_int32_t st_clears;
  209. u_int32_t st_destroys;
  210. u_int32_t st_max_locks;
  211. } REGMAINT_STAT;
  212. typedef struct __db_regmaint_t {
  213. u_int32_t  reglocks; /* Maximum # of mutexes we track. */
  214. u_int32_t  regmutex_hint; /* Hint for next slot */
  215. REGMAINT_STAT stat; /* Stats */
  216. roff_t    regmutexes[1]; /* Region mutexes in use. */
  217. } REGMAINT;
  218. /*
  219.  * R_ADDR Return a per-process address for a shared region offset.
  220.  * R_OFFSET Return a shared region offset for a per-process address.
  221.  *
  222.  * !!!
  223.  * R_OFFSET should really be returning a ptrdiff_t, but that's not yet
  224.  * portable.  We use u_int32_t, which restricts regions to 4Gb in size.
  225.  */
  226. #define R_ADDR(base, offset)
  227. ((void *)((u_int8_t *)((base)->addr) + offset))
  228. #define R_OFFSET(base, p)
  229. ((u_int32_t)((u_int8_t *)(p) - (u_int8_t *)(base)->addr))
  230. /*
  231.  * R_LOCK Lock/unlock a region.
  232.  * R_UNLOCK
  233.  */
  234. #define R_LOCK(dbenv, reginfo)
  235. MUTEX_LOCK(dbenv, &(reginfo)->rp->mutex, (dbenv)->lockfhp)
  236. #define R_UNLOCK(dbenv, reginfo)
  237. MUTEX_UNLOCK(dbenv, &(reginfo)->rp->mutex)
  238. /* PANIC_CHECK: Check to see if the DB environment is dead. */
  239. #define PANIC_CHECK(dbenv)
  240. if (DB_GLOBAL(db_panic) &&
  241.     (dbenv)->reginfo != NULL && ((REGENV *)
  242.     ((REGINFO *)(dbenv)->reginfo)->primary)->panic != 0)
  243. return (DB_RUNRECOVERY);
  244. /*
  245.  * All regions are created on 8K boundaries out of sheer paranoia, so that
  246.  * we don't make some underlying VM unhappy.
  247.  */
  248. #define OS_ROUNDOFF(i, s) {
  249. (i) += (s) - 1;
  250. (i) -= (i) % (s);
  251. }
  252. #define OS_VMPAGESIZE (8 * 1024)
  253. #define OS_VMROUNDOFF(i) OS_ROUNDOFF(i, OS_VMPAGESIZE)
  254. #if defined(__cplusplus)
  255. }
  256. #endif