]>
Commit | Line | Data |
---|---|---|
065feab4 JM |
1 | /* |
2 | * Memory Pool implementation logic. | |
3 | */ | |
4 | ||
5 | #include "cache.h" | |
6 | #include "mem-pool.h" | |
7 | ||
8 | static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc) | |
9 | { | |
10 | struct mp_block *p; | |
11 | ||
12 | mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc; | |
13 | p = xmalloc(st_add(sizeof(struct mp_block), block_alloc)); | |
14 | p->next_block = mem_pool->mp_block; | |
15 | p->next_free = (char *)p->space; | |
16 | p->end = p->next_free + block_alloc; | |
17 | mem_pool->mp_block = p; | |
18 | ||
19 | return p; | |
20 | } | |
21 | ||
22 | void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len) | |
23 | { | |
24 | struct mp_block *p; | |
25 | void *r; | |
26 | ||
27 | /* round up to a 'uintmax_t' alignment */ | |
28 | if (len & (sizeof(uintmax_t) - 1)) | |
29 | len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1)); | |
30 | ||
31 | for (p = mem_pool->mp_block; p; p = p->next_block) | |
32 | if (p->end - p->next_free >= len) | |
33 | break; | |
34 | ||
35 | if (!p) { | |
36 | if (len >= (mem_pool->block_alloc / 2)) { | |
37 | mem_pool->pool_alloc += len; | |
38 | return xmalloc(len); | |
39 | } | |
40 | ||
41 | p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc); | |
42 | } | |
43 | ||
44 | r = p->next_free; | |
45 | p->next_free += len; | |
46 | return r; | |
47 | } | |
48 | ||
49 | void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size) | |
50 | { | |
51 | size_t len = st_mult(count, size); | |
52 | void *r = mem_pool_alloc(mem_pool, len); | |
53 | memset(r, 0, len); | |
54 | return r; | |
55 | } |