region.h
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:11k
源码类别:

MySQL数据库

开发平台:

Visual C++

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