/[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

Annotation of /trunk/mempool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Sat Oct 6 16:26:06 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC3/mempool.c
File MIME type: text/plain
File size: 5008 byte(s)
dynamips-0.2.7-RC3

1 dpavlin 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