]> mj.ucw.cz Git - moe.git/blob - ucw/eltpool.h
Merge commit '700824d3e9bce9219819e4e5096ab94da301d44b' from branch bernard/master
[moe.git] / ucw / eltpool.h
1 /*
2  *      UCW Library -- Fast Allocator for Fixed-Size Elements
3  *
4  *      (c) 2007 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_ELTPOOL_H
11 #define _UCW_ELTPOOL_H
12
13 /***
14  * [[defs]]
15  * Definitions
16  * -----------
17  ***/
18
19 /**
20  * Memory pool of fixed-sized elements.
21  * You should use this one as an opaque handle only, the insides are internal.
22  **/
23 struct eltpool {
24   struct eltpool_chunk *first_chunk;
25   struct eltpool_free *first_free;
26   uns elt_size;
27   uns chunk_size;
28   uns elts_per_chunk;
29   uns num_allocated;            // Just for debugging
30   uns num_chunks;
31 };
32
33 struct eltpool_chunk {
34   struct eltpool_chunk *next;
35   /* Chunk data continue here */
36 };
37
38 struct eltpool_free {
39   struct eltpool_free *next;
40 };
41
42 /***
43  * [[basic]]
44  * Basic manipulation
45  * ------------------
46  ***/
47
48 /**
49  * Create a new memory pool for elements of @elt_size bytes.
50  * The pool will allocate chunks of at least @elts_per_chunk elements.
51  * Higher numbers lead to better allocation times but also to bigger
52  * unused memory blocks. Call @ep_delete() to free all pool's resources.
53  **/
54 struct eltpool *ep_new(uns elt_size, uns elts_per_chunk);
55
56 /**
57  * Release a memory pool created by @ep_new() including all
58  * elements allocated from that pool.
59  **/
60 void ep_delete(struct eltpool *pool);
61
62 /**
63  * Return the total number of bytes allocated by a given
64  * memory pool including all internals.
65  **/
66 u64 ep_total_size(struct eltpool *pool);
67
68 /***
69  * [[alloc]]
70  * Allocation routines
71  * -------------------
72  ***/
73
74 void *ep_alloc_slow(struct eltpool *pool); /* Internal. Do not call directly. */
75 /**
76  * Allocate a new element on a given memory pool.
77  * The results is always aligned to a multiple of the element's size.
78  **/
79 static inline void *ep_alloc(struct eltpool *pool)
80 {
81   pool->num_allocated++;
82 #ifdef CONFIG_FAKE_ELTPOOL
83   return xmalloc(pool->elt_size);
84 #else
85   struct eltpool_free *elt;
86   if (elt = pool->first_free)
87     pool->first_free = elt->next;
88   else
89     elt = ep_alloc_slow(pool);
90   return elt;
91 #endif
92 }
93
94 /**
95  * Release an element previously allocated by @ep_alloc().
96  * Note thet the memory is not really freed (until @mp_delete()),
97  * but it can be reused by future @ep_alloc()'s.
98  **/
99 static inline void ep_free(struct eltpool *pool, void *p)
100 {
101   pool->num_allocated--;
102 #ifdef CONFIG_FAKE_ELTPOOL
103   (void) pool;
104   xfree(p);
105 #else
106   struct eltpool_free *elt = p;
107   elt->next = pool->first_free;
108   pool->first_free = elt;
109 #endif
110 }
111
112 #endif