/[dynamips]/trunk/mempool.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/mempool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (11 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 5008 byte(s)
make working copy

1 /*
2 * Copyright (c) 1999-2006 Christophe Fillot.
3 * E-mail: cf@utc.fr
4 *
5 * mempool.c: Simple Memory Pools.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <signal.h>
15 #include <fcntl.h>
16 #include <ctype.h>
17 #include <time.h>
18 #include <sys/time.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <assert.h>
22
23 #include "utils.h"
24 #include "mempool.h"
25
26 /*
27 * Internal function used to allocate a memory block, and do basic operations
28 * on it. It does not manipulate pools, so no mutex is needed.
29 */
30 static inline memblock_t *memblock_alloc(size_t size,int zeroed)
31 {
32 memblock_t *block;
33 size_t total_size;
34
35 total_size = size + sizeof(memblock_t);
36 if (!(block = malloc(total_size)))
37 return NULL;
38
39 if (zeroed)
40 memset(block,0,total_size);
41
42 block->tag = MEMBLOCK_TAG;
43 block->block_size = size;
44 block->prev = block->next = NULL;
45 return block;
46 }
47
48 /* Insert block in linked list */
49 static inline void memblock_insert(mempool_t *pool,memblock_t *block)
50 {
51 MEMPOOL_LOCK(pool);
52
53 pool->nr_blocks++;
54 pool->total_size += block->block_size;
55
56 block->prev = NULL;
57 block->next = pool->block_list;
58
59 if (block->next)
60 block->next->prev = block;
61
62 pool->block_list = block;
63
64 MEMPOOL_UNLOCK(pool);
65 }
66
67 /* Remove block from linked list */
68 static inline void memblock_delete(mempool_t *pool,memblock_t *block)
69 {
70 MEMPOOL_LOCK(pool);
71
72 pool->nr_blocks--;
73 pool->total_size -= block->block_size;
74
75 if (!block->prev)
76 pool->block_list = block->next;
77 else
78 block->prev->next = block->next;
79
80 if (block->next)
81 block->next->prev = block->prev;
82
83 block->next = block->prev = NULL;
84 MEMPOOL_UNLOCK(pool);
85 }
86
87 /* Allocate a new block in specified pool (internal function) */
88 static inline void *mp_alloc_inline(mempool_t *pool,size_t size,int zeroed)
89 {
90 memblock_t *block;
91
92 if (!(block = memblock_alloc(size,zeroed)))
93 return NULL;
94
95 block->pool = pool;
96 memblock_insert(pool,block);
97 return(block->data);
98 }
99
100 /* Allocate a new block in specified pool */
101 void *mp_alloc(mempool_t *pool,size_t size)
102 {
103 return(mp_alloc_inline(pool,size,TRUE));
104 }
105
106 /* Allocate a new block which will not be zeroed */
107 void *mp_alloc_n0(mempool_t *pool,size_t size)
108 {
109 return(mp_alloc_inline(pool,size,FALSE));
110 }
111
112 /* Reallocate a block */
113 void *mp_realloc(void *addr,size_t new_size)
114 {
115 memblock_t *ptr,*block = (memblock_t *)addr - 1;
116 mempool_t *pool;
117 size_t total_size;
118
119 assert(block->tag == MEMBLOCK_TAG);
120 pool = block->pool;
121
122 /* remove this block from list */
123 memblock_delete(pool,block);
124
125 /* reallocate block with specified size */
126 total_size = new_size + sizeof(memblock_t);
127
128 if (!(ptr = realloc(block,total_size))) {
129 memblock_insert(pool,block);
130 return NULL;
131 }
132
133 ptr->block_size = new_size;
134 memblock_insert(pool,ptr);
135 return ptr->data;
136 }
137
138 /* Allocate a new memory block and copy data into it */
139 void *mp_dup(mempool_t *pool,void *data,size_t size)
140 {
141 void *p;
142
143 if ((p = mp_alloc_n0(pool,size)))
144 memcpy(p,data,size);
145
146 return p;
147 }
148
149 /* Duplicate specified string and insert it in a memory pool */
150 char *mp_strdup(mempool_t *pool,char *str)
151 {
152 char *new_str;
153
154 if ((new_str = mp_alloc(pool,strlen(str)+1)) == NULL)
155 return NULL;
156
157 strcpy(new_str,str);
158 return new_str;
159 }
160
161 /* Free block at specified address */
162 int mp_free(void *addr)
163 {
164 memblock_t *block = (memblock_t *)addr - 1;
165 mempool_t *pool;
166
167 if (addr != NULL) {
168 assert(block->tag == MEMBLOCK_TAG);
169 pool = block->pool;
170
171 memblock_delete(pool,block);
172 memset(block,0,sizeof(memblock_t));
173 free(block);
174 }
175
176 return(0);
177 }
178
179 /* Free block at specified address and clean pointer */
180 int mp_free_ptr(void *addr)
181 {
182 void *p;
183
184 assert(addr != NULL);
185 p = *(void **)addr;
186 *(void **)addr = NULL;
187 mp_free(p);
188 return(0);
189 }
190
191 /* Free all blocks of specified pool */
192 void mp_free_all_blocks(mempool_t *pool)
193 {
194 memblock_t *block,*next;
195
196 MEMPOOL_LOCK(pool);
197
198 for(block=pool->block_list;block;block=next) {
199 next = block->next;
200 free(block);
201 }
202
203 pool->block_list = NULL;
204 pool->nr_blocks = 0;
205 pool->total_size = 0;
206
207 MEMPOOL_UNLOCK(pool);
208 }
209
210 /* Free specified memory pool */
211 void mp_free_pool(mempool_t *pool)
212 {
213 mp_free_all_blocks(pool);
214
215 if (!(pool->flags & MEMPOOL_FIXED))
216 free(pool);
217 }
218
219 /* Create a new pool in a fixed memory area */
220 mempool_t *mp_create_fixed_pool(mempool_t *mp,char *name)
221 {
222 memset(mp,0,sizeof(*mp));
223
224 if (pthread_mutex_init(&mp->lock,NULL) != 0)
225 return NULL;
226
227 mp->name = name;
228 mp->block_list = NULL;
229 mp->flags = MEMPOOL_FIXED;
230 return mp;
231 }
232
233 /* Create a new pool */
234 mempool_t *mp_create_pool(char *name)
235 {
236 mempool_t *mp = malloc(sizeof(*mp));
237
238 if (!mp || !mp_create_fixed_pool(mp,name)) {
239 free(mp);
240 return NULL;
241 }
242
243 mp->flags = 0; /* clear "FIXED" flag */
244 return mp;
245 }

  ViewVC Help
Powered by ViewVC 1.1.26