comparison src/tools.c @ 12:79e9edf4c00a

Add redraw manager
author Thinker K.F. Li <thinker@branda.to>
date Mon, 28 Jul 2008 17:45:36 +0800
parents
children e06a4a667ce2
comparison
equal deleted inserted replaced
11:128af06c876c 12:79e9edf4c00a
1 #include <stdlib.h>
2 #include "tools.h"
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 */