Mercurial > MadButterfly
annotate src/tools.c @ 644:c9f8c7e6f57e
Add comment
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 28 Jul 2010 08:36:58 +0800 |
parents | 530bb7728546 |
children | 586e50f82c1f |
rev | line source |
---|---|
12 | 1 #include <stdlib.h> |
186
530bb7728546
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents:
185
diff
changeset
|
2 #include "mb_tools.h" |
12 | 3 |
4 | |
5 /*! \brief Small fixed size data elements management. | |
6 * | |
7 * It is used to management a large number of data elements | |
8 * they with the same memory size, a fixed size. It allocate | |
9 * a large block for a lot of elements a time for more efficiency | |
10 * utilization of memory. | |
11 * | |
12 * Elements with the size and in a large number usually be accessed | |
13 * very close in time. Allocate a large block for elements also | |
14 * increase cache hit rate. | |
15 * | |
16 * Blocks are keep track as a linking list. They are freed when | |
17 * the elmpool_t is freed. It costs overhead of size of a element | |
18 * for each block. We use memory of first element of blocks to | |
19 * be next pointer of linking list. So, it can not be used by user | |
20 * code. | |
21 */ | |
22 struct _elmpool { | |
23 int elm_sz; | |
24 int inc_num; | |
25 void *frees; | |
26 void *blks; /* list of allocated blocks. */ | |
27 }; | |
28 | |
29 /*! \brief Create a new data elements pool. | |
30 * | |
31 * elmpool_t provide a pool of fixed size elements to gain better | |
32 * utilization of memory. It try to allocate bigger memory blocks | |
33 * for multiple elements. | |
34 * | |
35 * \param elm_sz size of elements. | |
36 * \param inc_num is number of elments to allocate every time. (>= 16) | |
37 * \return A elmpool or NULL for error. | |
38 */ | |
39 elmpool_t *elmpool_new(int elm_sz, int inc_num) { | |
40 int _elm_sz; | |
41 elmpool_t *pool; | |
42 | |
43 if(inc_num < 16) | |
44 return NULL; | |
45 | |
46 if(elm_sz >= sizeof(void *)) | |
47 _elm_sz = elm_sz; | |
48 else | |
49 _elm_sz = sizeof(void *); | |
50 | |
51 pool = (elmpool_t *)malloc(sizeof(elmpool_t)); | |
52 if(pool == NULL) | |
53 return NULL; | |
54 | |
55 pool->elm_sz = _elm_sz; | |
56 if(inc_num == 0) | |
57 inc_num = 256; | |
58 pool->inc_num = inc_num; | |
59 pool->frees = NULL; | |
60 pool->blks = NULL; | |
61 | |
62 return pool; | |
63 } | |
64 | |
65 void *elmpool_elm_alloc(elmpool_t *pool) { | |
66 void *blk, *elm; | |
67 int elm_sz, inc_num; | |
68 int i; | |
69 | |
70 if(pool->frees == NULL) { | |
71 inc_num = pool->inc_num; | |
72 elm_sz = pool->elm_sz; | |
73 blk = malloc(elm_sz * inc_num); | |
74 if(blk == NULL) | |
75 return NULL; | |
76 | |
77 *(void **)blk = pool->blks; | |
78 pool->blks = blk; | |
79 | |
80 blk = blk + elm_sz; | |
81 pool->frees = blk; | |
82 for(i = 2; i < inc_num; i++) { | |
83 *(void **)blk = blk + elm_sz; | |
84 blk = *(void **)blk; | |
85 } | |
86 *(void **)blk = NULL; | |
87 } | |
88 | |
89 elm = pool->frees; | |
90 pool->frees = *(void **)elm; | |
91 | |
92 return elm; | |
93 } | |
94 | |
95 void elmpool_elm_free(elmpool_t *pool, void *elm) { | |
96 *(void **)elm = pool->frees; | |
97 pool->frees = elm; | |
98 } | |
99 | |
100 void elmpool_free(elmpool_t *pool) { | |
101 void *blk, *next_blk; | |
102 | |
103 blk = pool->blks; | |
104 while(blk) { | |
105 next_blk = *(void **)blk; | |
106 free(blk); | |
107 blk = next_blk; | |
108 } | |
109 } | |
110 | |
111 #ifdef UNITTEST | |
112 | |
113 #include <CUnit/Basic.h> | |
114 | |
115 void test_elmpool(void) { | |
116 elmpool_t *pool; | |
117 void *elm; | |
118 int i; | |
119 | |
120 pool = elmpool_new(64, 16); | |
121 for(i = 0; i < 15; i++) { | |
122 elm = elmpool_elm_alloc(pool); | |
123 CU_ASSERT(elm != NULL); | |
124 } | |
125 CU_ASSERT(pool->frees == NULL); | |
126 | |
127 for(i = 0; i < 15; i++) { | |
128 elm = elmpool_elm_alloc(pool); | |
129 CU_ASSERT(elm != NULL); | |
130 } | |
131 CU_ASSERT(pool->frees == NULL); | |
132 | |
133 elmpool_elm_free(pool, elm); | |
134 CU_ASSERT(pool->frees == elm); | |
135 | |
136 elm = elmpool_elm_alloc(pool); | |
137 CU_ASSERT(elm != NULL); | |
138 CU_ASSERT(pool->frees == NULL); | |
139 | |
140 elmpool_free(pool); | |
141 } | |
142 | |
143 CU_pSuite get_tools_suite(void) { | |
144 CU_pSuite suite; | |
145 | |
146 suite = CU_add_suite("Suite_tools", NULL, NULL); | |
147 CU_ADD_TEST(suite, test_elmpool); | |
148 | |
149 return suite; | |
150 } | |
151 | |
152 #endif /* UNITTEST */ |