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