Asterisk - The Open Source Telephony Project GIT-master-f36a736
Macros | Functions
mpool.c File Reference
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../include/db.h"
#include <mpool.h>
Include dependency graph for mpool.c:

Go to the source code of this file.

Macros

#define __APPLE__
 
#define __MPOOLINTERFACE_PRIVATE
 
#define mpool_close   __mpool_close
 
#define mpool_filter   __mpool_filter
 
#define mpool_get   __mpool_get
 
#define mpool_new   __mpool_new
 
#define mpool_open   __mpool_open
 
#define mpool_put   __mpool_put
 
#define mpool_sync   __mpool_sync
 

Functions

static BKT *mpool_bkt __P ((MPOOL *))
 
static int mpool_write __P ((MPOOL *, BKT *))
 
static BKT *mpool_look __P ((MPOOL *, pgno_t))
 
static BKTmpool_bkt (MPOOL *mp)
 
int mpool_close (MPOOL *mp)
 
void mpool_filter (MPOOL *mp, void *pgin, void *pgout, void *pgcookie)
 
void * mpool_get (MPOOL *mp, pgno_t pgno, u_int flags)
 
static BKTmpool_look (MPOOL *mp, pgno_t pgno)
 
void * mpool_new (MPOOL *mp, pgno_t *pgnoaddr)
 
MPOOLmpool_open (void *key, int fd, pgno_t pagesize, pgno_t maxcache)
 
int mpool_put (MPOOL *mp, void *page, u_int flags)
 
int mpool_sync (MPOOL *mp)
 
static int mpool_write (MPOOL *mp, BKT *bp)
 

Macro Definition Documentation

◆ __APPLE__

#define __APPLE__

Definition at line 316 of file mpool.c.

◆ __MPOOLINTERFACE_PRIVATE

#define __MPOOLINTERFACE_PRIVATE

Definition at line 50 of file mpool.c.

◆ mpool_close

#define mpool_close   __mpool_close

Definition at line 62 of file mpool.c.

◆ mpool_filter

#define mpool_filter   __mpool_filter

Definition at line 57 of file mpool.c.

◆ mpool_get

#define mpool_get   __mpool_get

Definition at line 59 of file mpool.c.

◆ mpool_new

#define mpool_new   __mpool_new

Definition at line 58 of file mpool.c.

◆ mpool_open

#define mpool_open   __mpool_open

Definition at line 56 of file mpool.c.

◆ mpool_put

#define mpool_put   __mpool_put

Definition at line 60 of file mpool.c.

◆ mpool_sync

#define mpool_sync   __mpool_sync

Definition at line 61 of file mpool.c.

Function Documentation

◆ __P() [1/3]

static BKT *mpool_bkt __P ( (MPOOL *)  )
static

◆ __P() [2/3]

static int mpool_write __P ( (MPOOL *, BKT *)  )
static

◆ __P() [3/3]

static BKT *mpool_look __P ( (MPOOL *, pgno_t )
static

◆ mpool_bkt()

static BKT * mpool_bkt ( MPOOL mp)
static

Definition at line 343 of file mpool.c.

345{
346 struct _hqh *head;
347 BKT *bp;
348
349 /* If under the max cached, always create a new page. */
350 if (mp->curcache < mp->maxcache)
351 goto new;
352
353 /*
354 * If the cache is max'd out, walk the lru list for a buffer we
355 * can flush. If we find one, write it (if necessary) and take it
356 * off any lists. If we don't find anything we grow the cache anyway.
357 * The cache never shrinks.
358 */
359 for (bp = mp->lqh.cqh_first;
360 bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
361 if (!(bp->flags & MPOOL_PINNED)) {
362 /* Flush if dirty. */
363 if (bp->flags & MPOOL_DIRTY &&
364 mpool_write(mp, bp) == RET_ERROR)
365 return (NULL);
366#ifdef STATISTICS
367 ++mp->pageflush;
368#endif
369 /* Remove from the hash and lru queues. */
370 head = &mp->hqh[HASHKEY(bp->pgno)];
371 CIRCLEQ_REMOVE(head, bp, hq);
372 CIRCLEQ_REMOVE(&mp->lqh, bp, q);
373#ifdef DEBUG
374 { void *spage;
375 spage = bp->page;
376 memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
377 bp->page = spage;
378 }
379#endif
380 return (bp);
381 }
382
383new: if ((bp = (BKT *) calloc(1, sizeof(BKT) + mp->pagesize)) == NULL)
384 return (NULL);
385#ifdef STATISTICS
386 ++mp->pagealloc;
387#endif
388#if defined(DEBUG) || defined(PURIFY)
389 memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
390#endif
391 bp->page = (char *)bp + sizeof(BKT);
392 ++mp->curcache;
393 return (bp);
394}
#define calloc(a, b)
Definition: astmm.h:155
#define RET_ERROR
Definition: db.h:51
static int mpool_write(MPOOL *mp, BKT *bp)
Definition: mpool.c:401
#define MPOOL_PINNED
Definition: mpool.h:62
#define HASHKEY(pgno)
Definition: mpool.h:52
#define MPOOL_DIRTY
Definition: mpool.h:61
#define CIRCLEQ_REMOVE(head, elm, field)
Definition: queue.h:482
#define NULL
Definition: resample.c:96
pgno_t curcache
Definition: mpool.h:70
pgno_t maxcache
Definition: mpool.h:71
u_long pagesize
Definition: mpool.h:73
Definition: mpool.h:55
pgno_t pgno
Definition: mpool.h:59
void * page
Definition: mpool.h:58
u_int8_t flags
Definition: mpool.h:63

References calloc, CIRCLEQ_REMOVE, MPOOL::curcache, _bkt::flags, HASHKEY, MPOOL::maxcache, MPOOL_DIRTY, MPOOL_PINNED, mpool_write(), NULL, _bkt::page, MPOOL::pagesize, _bkt::pgno, and RET_ERROR.

Referenced by mpool_get(), and mpool_new().

◆ mpool_close()

int mpool_close ( MPOOL mp)

Definition at line 279 of file mpool.c.

281{
282 BKT *bp;
283
284 /* Free up any space allocated to the lru pages. */
285 while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
286 CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
287 free(bp);
288 }
289
290 /* Free the MPOOL cookie. */
291 free(mp);
292 return (RET_SUCCESS);
293}
#define RET_SUCCESS
Definition: db.h:52
void free()

References CIRCLEQ_REMOVE, free(), and RET_SUCCESS.

Referenced by __bt_close().

◆ mpool_filter()

void mpool_filter ( MPOOL mp,
void *  pgin,
void *  pgout,
void *  pgcookie 
)

Definition at line 114 of file mpool.c.

119{
120 mp->pgin = pgin;
121 mp->pgout = pgout;
122 mp->pgcookie = pgcookie;
123}
void * pgcookie
Definition: mpool.h:79

Referenced by __bt_open().

◆ mpool_get()

void * mpool_get ( MPOOL mp,
pgno_t  pgno,
u_int  flags 
)

Definition at line 165 of file mpool.c.

169{
170 struct _hqh *head;
171 BKT *bp;
172 off_t off;
173 int nr;
174
175 /* Check for attempt to retrieve a non-existent page. */
176 if (pgno >= mp->npages) {
177 errno = EINVAL;
178 return (NULL);
179 }
180
181#ifdef STATISTICS
182 ++mp->pageget;
183#endif
184
185 /* Check for a page that is cached. */
186 if ((bp = mpool_look(mp, pgno)) != NULL) {
187#ifdef DEBUG
188 if (bp->flags & MPOOL_PINNED) {
189 (void)fprintf(stderr,
190 "mpool_get: page %d already pinned\n", bp->pgno);
191 abort();
192 }
193#endif
194 /*
195 * Move the page to the head of the hash chain and the tail
196 * of the lru chain.
197 */
198 head = &mp->hqh[HASHKEY(bp->pgno)];
199 CIRCLEQ_REMOVE(head, bp, hq);
200 CIRCLEQ_INSERT_HEAD(head, bp, hq);
201 CIRCLEQ_REMOVE(&mp->lqh, bp, q);
202 CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
203
204 /* Return a pinned page. */
205 bp->flags |= MPOOL_PINNED;
206 return (bp->page);
207 }
208
209 /* Get a page from the cache. */
210 if ((bp = mpool_bkt(mp)) == NULL)
211 return (NULL);
212
213 /* Read in the contents. */
214#ifdef STATISTICS
215 ++mp->pageread;
216#endif
217 off = mp->pagesize * pgno;
218 if (lseek(mp->fd, off, SEEK_SET) != off)
219 return (NULL);
220 if ((u_long) (nr = read(mp->fd, bp->page, mp->pagesize))
221 != mp->pagesize) {
222 if (nr >= 0)
223 errno = EFTYPE;
224 return (NULL);
225 }
226
227 /* Set the page number, pin the page. */
228 bp->pgno = pgno;
229 bp->flags = MPOOL_PINNED;
230
231 /*
232 * Add the page to the head of the hash chain and the tail
233 * of the lru chain.
234 */
235 head = &mp->hqh[HASHKEY(bp->pgno)];
236 CIRCLEQ_INSERT_HEAD(head, bp, hq);
237 CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
238
239 /* Run through the user's filter. */
240 if (mp->pgin != NULL)
241 (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
242
243 return (bp->page);
244}
int errno
static BKT * mpool_bkt(MPOOL *mp)
Definition: mpool.c:343
static BKT * mpool_look(MPOOL *mp, pgno_t pgno)
Definition: mpool.c:430
#define CIRCLEQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:456
#define CIRCLEQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:466
pgno_t npages
Definition: mpool.h:72
int fd
Definition: mpool.h:74
#define EFTYPE

References CIRCLEQ_INSERT_HEAD, CIRCLEQ_INSERT_TAIL, CIRCLEQ_REMOVE, EFTYPE, errno, MPOOL::fd, _bkt::flags, HASHKEY, mpool_bkt(), mpool_look(), MPOOL_PINNED, MPOOL::npages, NULL, _bkt::page, MPOOL::pagesize, MPOOL::pgcookie, and _bkt::pgno.

Referenced by __bt_curdel(), __bt_delete(), __bt_first(), __bt_new(), __bt_pdelete(), __bt_put(), __bt_relink(), __bt_search(), __bt_seqadv(), __bt_seqset(), __bt_snext(), __bt_split(), __bt_sprev(), __bt_stkacq(), __ovfl_delete(), __ovfl_get(), __rec_open(), __rec_search(), bt_fast(), bt_meta(), bt_page(), bt_preserve(), and nroot().

◆ mpool_look()

static BKT * mpool_look ( MPOOL mp,
pgno_t  pgno 
)
static

Definition at line 430 of file mpool.c.

433{
434 struct _hqh *head;
435 BKT *bp;
436
437 head = &mp->hqh[HASHKEY(pgno)];
438 for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
439 if (bp->pgno == pgno) {
440#ifdef STATISTICS
441 ++mp->cachehit;
442#endif
443 return (bp);
444 }
445#ifdef STATISTICS
446 ++mp->cachemiss;
447#endif
448 return (NULL);
449}

References HASHKEY, NULL, and _bkt::pgno.

Referenced by mpool_get().

◆ mpool_new()

void * mpool_new ( MPOOL mp,
pgno_t pgnoaddr 
)

Definition at line 130 of file mpool.c.

133{
134 struct _hqh *head;
135 BKT *bp;
136
137 if (mp->npages == MAX_PAGE_NUMBER) {
138 (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
139 abort();
140 }
141#ifdef STATISTICS
142 ++mp->pagenew;
143#endif
144 /*
145 * Get a BKT from the cache. Assign a new page number, attach
146 * it to the head of the hash chain, the tail of the lru chain,
147 * and return.
148 */
149 if ((bp = mpool_bkt(mp)) == NULL)
150 return (NULL);
151 *pgnoaddr = bp->pgno = mp->npages++;
152 bp->flags = MPOOL_PINNED;
153
154 head = &mp->hqh[HASHKEY(bp->pgno)];
155 CIRCLEQ_INSERT_HEAD(head, bp, hq);
156 CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
157 return (bp->page);
158}
#define MAX_PAGE_NUMBER
Definition: db.h:77

References CIRCLEQ_INSERT_HEAD, CIRCLEQ_INSERT_TAIL, _bkt::flags, HASHKEY, MAX_PAGE_NUMBER, mpool_bkt(), MPOOL_PINNED, MPOOL::npages, NULL, _bkt::page, and _bkt::pgno.

Referenced by __bt_new(), and nroot().

◆ mpool_open()

MPOOL * mpool_open ( void *  key,
int  fd,
pgno_t  pagesize,
pgno_t  maxcache 
)

Definition at line 74 of file mpool.c.

78{
79 struct stat sb;
80 MPOOL *mp;
81 int entry;
82
83 /*
84 * Get information about the file.
85 *
86 * XXX
87 * We don't currently handle pipes, although we should.
88 */
89 if (fstat(fd, &sb))
90 return (NULL);
91 if (!S_ISREG(sb.st_mode)) {
92 errno = ESPIPE;
93 return (NULL);
94 }
95
96 /* Allocate and initialize the MPOOL cookie. */
97 if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
98 return (NULL);
99 CIRCLEQ_INIT(&mp->lqh);
100 for (entry = 0; entry < HASHSIZE; ++entry)
101 CIRCLEQ_INIT(&mp->hqh[entry]);
102 mp->maxcache = maxcache;
103 mp->npages = sb.st_size / pagesize;
104 mp->pagesize = pagesize;
105 mp->fd = fd;
106 return (mp);
107}
#define HASHSIZE
Definition: mpool.h:51
#define CIRCLEQ_INIT(head)
Definition: queue.h:431
Definition: mpool.h:66
Definition: search.h:40

References calloc, CIRCLEQ_INIT, errno, HASHSIZE, and NULL.

Referenced by __bt_open().

◆ mpool_put()

int mpool_put ( MPOOL mp,
void *  page,
u_int  flags 
)

Definition at line 251 of file mpool.c.

255{
256 BKT *bp;
257
258#ifdef STATISTICS
259 ++mp->pageput;
260#endif
261 bp = (BKT *)((char *)page - sizeof(BKT));
262#ifdef DEBUG
263 if (!(bp->flags & MPOOL_PINNED)) {
264 (void)fprintf(stderr,
265 "mpool_put: page %d not pinned\n", bp->pgno);
266 abort();
267 }
268#endif
269 bp->flags &= ~MPOOL_PINNED;
270 bp->flags |= flags & MPOOL_DIRTY;
271 return (RET_SUCCESS);
272}
struct _bkt BKT

References _bkt::flags, MPOOL_DIRTY, MPOOL_PINNED, _bkt::pgno, and RET_SUCCESS.

Referenced by __bt_bdelete(), __bt_close(), __bt_curdel(), __bt_delete(), __bt_fd(), __bt_first(), __bt_free(), __bt_get(), __bt_pdelete(), __bt_put(), __bt_relink(), __bt_search(), __bt_seq(), __bt_seqadv(), __bt_seqset(), __bt_snext(), __bt_split(), __bt_sprev(), __bt_stkacq(), __bt_sync(), __ovfl_delete(), __ovfl_get(), __ovfl_put(), __rec_close(), __rec_delete(), __rec_fd(), __rec_get(), __rec_iput(), __rec_open(), __rec_put(), __rec_search(), __rec_seq(), __rec_sync(), bt_broot(), bt_fast(), bt_meta(), bt_page(), bt_preserve(), bt_rroot(), nroot(), and rec_rdelete().

◆ mpool_sync()

int mpool_sync ( MPOOL mp)

Definition at line 300 of file mpool.c.

302{
303 BKT *bp;
304
305 /* Walk the lru chain, flushing any dirty pages to disk. */
306 for (bp = mp->lqh.cqh_first;
307 bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
308 if (bp->flags & MPOOL_DIRTY &&
309 mpool_write(mp, bp) == RET_ERROR)
310 return (RET_ERROR);
311
312 /* Sync the file descriptor. */
313 return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
314}

References MPOOL::fd, _bkt::flags, MPOOL_DIRTY, mpool_write(), RET_ERROR, and RET_SUCCESS.

Referenced by __bt_sync().

◆ mpool_write()

static int mpool_write ( MPOOL mp,
BKT bp 
)
static

Definition at line 401 of file mpool.c.

404{
405 off_t off;
406
407#ifdef STATISTICS
408 ++mp->pagewrite;
409#endif
410
411 /* Run through the user's filter. */
412 if (mp->pgout)
413 (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
414
415 off = mp->pagesize * bp->pgno;
416 if (lseek(mp->fd, off, SEEK_SET) != off)
417 return (RET_ERROR);
418 if ((u_long) write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
419 return (RET_ERROR);
420
421 bp->flags &= ~MPOOL_DIRTY;
422 return (RET_SUCCESS);
423}

References MPOOL::fd, _bkt::flags, _bkt::page, MPOOL::pagesize, MPOOL::pgcookie, _bkt::pgno, RET_ERROR, and RET_SUCCESS.

Referenced by mpool_bkt(), and mpool_sync().