Update from db-2.3.12.
[kopensolaris-gnu/glibc.git] / db2 / include / mp.h
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996, 1997
5  *      Sleepycat Software.  All rights reserved.
6  *
7  *      @(#)mp.h        10.19 (Sleepycat) 10/25/97
8  */
9
10 struct __bh;            typedef struct __bh BH;
11 struct __db_mpreg;      typedef struct __db_mpreg DB_MPREG;
12 struct __mpool;         typedef struct __mpool MPOOL;
13 struct __mpoolfile;     typedef struct __mpoolfile MPOOLFILE;
14
15                                         /* Default mpool name. */
16 #define DB_DEFAULT_MPOOL_FILE   "__db_mpool.share"
17
18 /*
19  *  We default to 128K (16 8K pages) if the user doesn't specify, and
20  * require a minimum of 20K.
21  */
22 #define DB_CACHESIZE_DEF        (128 * 1024)
23 #define DB_CACHESIZE_MIN        ( 20 * 1024)
24
25 #define INVALID         0               /* Invalid shared memory offset. */
26 #define TEMPORARY       "<tmp>"         /* Temporary file name. */
27
28 /*
29  * There are three ways we do locking in the mpool code:
30  *
31  * Locking a handle mutex to provide concurrency for DB_THREAD operations.
32  * Locking the region mutex to provide mutual exclusion while reading and
33  *    writing structures in the shared region.
34  * Locking buffer header mutexes during I/O.
35  *
36  * The first will not be further described here.  We use the shared mpool
37  * region lock to provide mutual exclusion while reading/modifying all of
38  * the data structures, including the buffer headers.  We use a per-buffer
39  * header lock to wait on buffer I/O.  The order of locking is as follows:
40  *
41  * Searching for a buffer:
42  *      Acquire the region lock.
43  *      Find the buffer header.
44  *      Increment the reference count (guarantee the buffer stays).
45  *      If the BH_LOCKED flag is set (I/O is going on):
46  *              Release the region lock.
47  *              Request the buffer lock.
48  *              The I/O will complete...
49  *              Acquire the buffer lock.
50  *              Release the buffer lock.
51  *              Acquire the region lock.
52  *      Return the buffer.
53  *
54  * Reading/writing a buffer:
55  *      Acquire the region lock.
56  *      Find/create the buffer header.
57  *      If reading, increment the reference count (guarantee the buffer stays).
58  *      Set the BH_LOCKED flag.
59  *      Acquire the buffer lock (guaranteed not to block).
60  *      Release the region lock.
61  *      Do the I/O and/or initialize buffer contents.
62  *      Acquire the region lock.
63  *      Clear the BH_LOCKED flag.
64  *      Release the region lock.
65  *      Release the buffer lock.
66  *      If reading, return the buffer.
67  *
68  * Pointers to DB_MPOOL, MPOOL, DB_MPOOLFILE and MPOOLFILE structures are not
69  * reacquired when a region lock is reacquired because they couldn't have been
70  * closed/discarded and because they never move in memory.
71  */
72 #define LOCKINIT(dbmp, mutexp)                                          \
73         if (F_ISSET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION))               \
74                 (void)__db_mutex_init(mutexp, (dbmp)->fd)
75
76 #define LOCKHANDLE(dbmp, mutexp)                                        \
77         if (F_ISSET(dbmp, MP_LOCKHANDLE))                               \
78                 (void)__db_mutex_lock(mutexp, (dbmp)->fd)
79 #define UNLOCKHANDLE(dbmp, mutexp)                                      \
80         if (F_ISSET(dbmp, MP_LOCKHANDLE))                               \
81                 (void)__db_mutex_unlock(mutexp, (dbmp)->fd)
82
83 #define LOCKREGION(dbmp)                                                \
84         if (F_ISSET(dbmp, MP_LOCKREGION))                               \
85                 (void)__db_mutex_lock(&((RLAYOUT *)(dbmp)->mp)->lock,   \
86                     (dbmp)->fd)
87 #define UNLOCKREGION(dbmp)                                              \
88         if (F_ISSET(dbmp, MP_LOCKREGION))                               \
89                 (void)__db_mutex_unlock(&((RLAYOUT *)(dbmp)->mp)->lock, \
90                 (dbmp)->fd)
91
92 #define LOCKBUFFER(dbmp, bhp)                                           \
93         if (F_ISSET(dbmp, MP_LOCKREGION))                               \
94                 (void)__db_mutex_lock(&(bhp)->mutex, (dbmp)->fd)
95 #define UNLOCKBUFFER(dbmp, bhp)                                         \
96         if (F_ISSET(dbmp, MP_LOCKREGION))                               \
97                 (void)__db_mutex_unlock(&(bhp)->mutex, (dbmp)->fd)
98
99 /*
100  * DB_MPOOL --
101  *      Per-process memory pool structure.
102  */
103 struct __db_mpool {
104 /* These fields need to be protected for multi-threaded support. */
105         db_mutex_t      *mutexp;        /* Structure lock. */
106
107                                         /* List of pgin/pgout routines. */
108         LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
109
110                                         /* List of DB_MPOOLFILE's. */
111         TAILQ_HEAD(__db_mpoolfileh, __db_mpoolfile) dbmfq;
112
113 /* These fields are not protected. */
114         DB_ENV     *dbenv;              /* Reference to error information. */
115
116         MPOOL      *mp;                 /* Address of the shared MPOOL. */
117
118         void       *maddr;              /* Address of mmap'd region. */
119         void       *addr;               /* Address of shalloc() region. */
120
121         DB_HASHTAB *htab;               /* Hash table of bucket headers. */
122
123         int         fd;                 /* Underlying mmap'd fd. */
124
125
126 #define MP_ISPRIVATE    0x01            /* Private, so local memory. */
127 #define MP_LOCKHANDLE   0x02            /* Threaded, lock handles and region. */
128 #define MP_LOCKREGION   0x04            /* Concurrent access, lock region. */
129         u_int32_t  flags;
130 };
131
132 /*
133  * DB_MPREG --
134  *      DB_MPOOL registry of pgin/pgout functions.
135  */
136 struct __db_mpreg {
137         LIST_ENTRY(__db_mpreg) q;       /* Linked list. */
138
139         int ftype;                      /* File type. */
140                                         /* Pgin, pgout routines. */
141         int (*pgin) __P((db_pgno_t, void *, DBT *));
142         int (*pgout) __P((db_pgno_t, void *, DBT *));
143 };
144
145 /*
146  * DB_MPOOLFILE --
147  *      Per-process DB_MPOOLFILE information.
148  */
149 struct __db_mpoolfile {
150 /* These fields need to be protected for multi-threaded support. */
151         db_mutex_t      *mutexp;        /* Structure lock. */
152
153         int        fd;                  /* Underlying file descriptor. */
154
155         u_int32_t pinref;               /* Pinned block reference count. */
156
157 /* These fields are not protected. */
158         TAILQ_ENTRY(__db_mpoolfile) q;  /* Linked list of DB_MPOOLFILE's. */
159
160         char      *path;                /* Initial file path. */
161         DB_MPOOL  *dbmp;                /* Overlying DB_MPOOL. */
162         MPOOLFILE *mfp;                 /* Underlying MPOOLFILE. */
163
164         void      *addr;                /* Address of mmap'd region. */
165         size_t     len;                 /* Length of mmap'd region. */
166
167 /* These fields need to be protected for multi-threaded support. */
168 #define MP_PATH_ALLOC   0x001           /* Path is allocated memory. */
169 #define MP_PATH_TEMP    0x002           /* Backing file is a temporary. */
170 #define MP_READONLY     0x004           /* File is readonly. */
171 #define MP_UPGRADE      0x008           /* File descriptor is readwrite. */
172 #define MP_UPGRADE_FAIL 0x010           /* Upgrade wasn't possible. */
173         u_int32_t  flags;
174 };
175
176 /*
177  * MPOOL --
178  *      Shared memory pool region.  One of these is allocated in shared
179  *      memory, and describes the pool.
180  */
181 struct __mpool {
182         RLAYOUT     rlayout;            /* General region information. */
183
184         SH_TAILQ_HEAD(__bhq) bhq;       /* LRU list of buckets. */
185         SH_TAILQ_HEAD(__bhfq) bhfq;     /* Free buckets. */
186         SH_TAILQ_HEAD(__mpfq) mpfq;     /* List of MPOOLFILEs. */
187
188         /*
189          * We make the assumption that the early pages of the file are far
190          * more likely to be retrieved than the later pages, which means
191          * that the top bits are more interesting for hashing since they're
192          * less likely to collide.  On the other hand, since 512 4K pages
193          * represents a 2MB file, only the bottom 9 bits of the page number
194          * are likely to be set.  We XOR in the offset in the MPOOL of the
195          * MPOOLFILE that backs this particular page, since that should also
196          * be unique for the page.
197          */
198 #define BUCKET(mp, mf_offset, pgno)                                     \
199         (((pgno) ^ ((mf_offset) << 9)) % (mp)->htab_buckets)
200
201         size_t      htab;               /* Hash table offset. */
202         size_t      htab_buckets;       /* Number of hash table entries. */
203
204         DB_LSN      lsn;                /* Maximum checkpoint LSN. */
205         int         lsn_cnt;            /* Checkpoint buffers left to write. */
206
207         DB_MPOOL_STAT stat;             /* Global mpool statistics. */
208
209 #define MP_LSN_RETRY    0x01            /* Retry all BH_WRITE buffers. */
210         u_int32_t  flags;
211 };
212
213 /*
214  * MPOOLFILE --
215  *      Shared DB_MPOOLFILE information.
216  */
217 struct __mpoolfile {
218         SH_TAILQ_ENTRY  q;              /* List of MPOOLFILEs */
219
220         u_int32_t ref;                  /* Reference count. */
221
222         int       ftype;                /* File type. */
223         int       can_mmap;             /* If the file can be mmap'd. */
224
225         int       lsn_off;              /* Page's LSN offset. */
226
227         size_t    path_off;             /* File name location. */
228
229         size_t    fileid_off;           /* File identification location. */
230
231         size_t    pgcookie_len;         /* Pgin/pgout cookie length. */
232         size_t    pgcookie_off;         /* Pgin/pgout cookie location. */
233
234         int       lsn_cnt;              /* Checkpoint buffers left to write. */
235
236         DB_MPOOL_FSTAT stat;            /* Per-file mpool statistics. */
237 };
238
239 /*
240  * BH --
241  *      Buffer header.
242  */
243 struct __bh {
244         db_mutex_t      mutex;          /* Structure lock. */
245
246         u_int16_t       ref;            /* Reference count. */
247
248 #define BH_CALLPGIN     0x001           /* Page needs to be reworked... */
249 #define BH_DIRTY        0x002           /* Page was modified. */
250 #define BH_DISCARD      0x004           /* Page is useless. */
251 #define BH_LOCKED       0x008           /* Page is locked (I/O in progress). */
252 #define BH_TRASH        0x010           /* Page is garbage. */
253 #define BH_WRITE        0x020           /* Page scheduled for writing. */
254         u_int16_t  flags;
255
256         SH_TAILQ_ENTRY  q;              /* LRU queue. */
257         SH_TAILQ_ENTRY  hq;             /* MPOOL hash bucket queue. */
258
259         db_pgno_t pgno;                 /* Underlying MPOOLFILE page number. */
260         size_t    mf_offset;            /* Associated MPOOLFILE offset. */
261
262         /*
263          * !!!
264          * This array must be size_t aligned -- the DB access methods put PAGE
265          * and other structures into it, and expect to be able to access them
266          * directly.  (We guarantee size_t alignment in the db_mpool(3) manual
267          * page as well.)
268          */
269         u_int8_t   buf[1];              /* Variable length data. */
270 };
271
272 #include "mp_ext.h"