]> mj.ucw.cz Git - libucw.git/blob - ucw/eltpool.h
Opt: defined user interface
[libucw.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  * Element pools can be treated as <<trans:respools,resources>>, see <<trans:res_eltpool()>>.
55  **/
56 struct eltpool *ep_new(uns elt_size, uns elts_per_chunk);
57
58 /**
59  * Release a memory pool created by @ep_new() including all
60  * elements allocated from that pool.
61  **/
62 void ep_delete(struct eltpool *pool);
63
64 /**
65  * Return the total number of bytes allocated by a given
66  * memory pool including all internals.
67  **/
68 u64 ep_total_size(struct eltpool *pool);
69
70 /***
71  * [[alloc]]
72  * Allocation routines
73  * -------------------
74  ***/
75
76 void *ep_alloc_slow(struct eltpool *pool); /* Internal. Do not call directly. */
77 /**
78  * Allocate a new element on a given memory pool.
79  * The results is always aligned to a multiple of the element's size.
80  **/
81 static inline void *ep_alloc(struct eltpool *pool)
82 {
83   pool->num_allocated++;
84 #ifdef CONFIG_UCW_FAKE_ELTPOOL
85   return xmalloc(pool->elt_size);
86 #else
87   struct eltpool_free *elt;
88   if (elt = pool->first_free)
89     pool->first_free = elt->next;
90   else
91     elt = ep_alloc_slow(pool);
92   return elt;
93 #endif
94 }
95
96 /**
97  * Release an element previously allocated by @ep_alloc().
98  * Note thet the memory is not really freed (until @mp_delete()),
99  * but it can be reused by future @ep_alloc()'s.
100  **/
101 static inline void ep_free(struct eltpool *pool, void *p)
102 {
103   pool->num_allocated--;
104 #ifdef CONFIG_UCW_FAKE_ELTPOOL
105   (void) pool;
106   xfree(p);
107 #else
108   struct eltpool_free *elt = p;
109   elt->next = pool->first_free;
110   pool->first_free = elt;
111 #endif
112 }
113
114 #endif