ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/libpeak-0.1.2/peak/mem_pool.c
Revision: 3251
Committed: Wed Apr 2 16:58:30 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 5929 byte(s)
Log Message:
- Imported libpeak-0.1.2

File Contents

# Content
1 /* PEAK Library
2 *
3 * Copyright (c) 2003
4 * Stephane Thiell <mbuna@bugged.org>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30 #define RCSID "$Id: mem_pool.c,v 1.2 2004/01/08 16:39:55 mbuna Exp $"
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <peak/mem_pool.h>
37 #include <peak/alloc.h>
38 #include "internal.h"
39
40 #include <assert.h>
41 #include <stdarg.h>
42 #include <sys/types.h>
43
44 #define PEAK_MEM_ALIGN(x,s) \
45 (int)(((uint32_t)(x) + ((s)-1)) & ~((signed)((s)-1)))
46
47 static void __peak_mem_pool_init(peak_mem_pool pool, va_list vp, void *ctcx);
48 static void __peak_mem_pool_finalize(peak_mem_pool pool);
49
50
51 typedef struct __peak_mem_pool_entry
52 {
53 struct __peak_mem_pool_entry * next;
54 } __peak_mem_pool_entry;
55
56 typedef struct __peak_mem_pool_chunk
57 {
58 struct __peak_mem_pool_chunk * next;
59 __peak_mem_pool_entry * chunk;
60 int size;
61 } __peak_mem_pool_chunk;
62
63 struct __peak_mem_pool
64 {
65 PEAK_STRUCT_RT_HEADER;
66 __peak_mem_pool_chunk * _heaphead; /* associated heap chunks list */
67 __peak_mem_pool_entry * _freehead; /* head of available
68 * mem_pool_entry list
69 */
70 unsigned int _object_size;
71 unsigned int _power; /* last power used */
72 unsigned int _size; /* actual total size */
73 unsigned int _allocated; /* allocated pointers */
74 };
75
76 PEAK_CLASS_BASE_DECLARE(mem_pool);
77
78 peak_mem_pool
79 peak_mem_pool_create(int object_size, int log_size)
80 {
81 return PEAK_CLASS_CONSTRUCT2(mem_pool, object_size, log_size);
82 }
83
84 static void
85 __peak_mem_pool_init(peak_mem_pool pool, va_list vp, void *ctcx)
86 {
87 unsigned int i, size, logsize;
88 __peak_mem_pool_entry * e;
89
90 size = (unsigned int)va_arg(vp, int);
91 logsize = (unsigned int)va_arg(vp, int);
92
93 if (size < sizeof(void*))
94 size = sizeof(void*);
95 else
96 size = PEAK_MEM_ALIGN(size, sizeof(void*));
97 /*TODO: vector/altivec align*/
98
99 pool->_object_size = size;
100 pool->_power = logsize > 2 ? logsize : 2;
101 pool->_size = 1 << pool->_power;
102 pool->_allocated = 0;
103
104 pool->_heaphead =
105 (__peak_mem_pool_chunk *)peak_allocate(sizeof(__peak_mem_pool_chunk));
106 pool->_heaphead->next = NULL;
107 pool->_heaphead->chunk =
108 (__peak_mem_pool_entry *)peak_allocate(pool->_size * pool->_object_size);
109 pool->_heaphead->size = pool->_size;
110
111 pool->_freehead = pool->_heaphead->chunk;
112 e = pool->_freehead;
113
114 for (i = 1; i < pool->_heaphead->size; i++, e = e->next)
115 e->next = (__peak_mem_pool_entry *)(((intptr_t)pool->_heaphead->chunk)
116 + (size_t)(i * pool->_object_size));
117 e->next = NULL;
118 }
119
120 static void
121 __peak_mem_pool_finalize(peak_mem_pool pool)
122 {
123 __peak_mem_pool_chunk *chunk, *next_chunk;
124
125 for (chunk = pool->_heaphead; chunk; chunk = next_chunk)
126 {
127 next_chunk = chunk->next;
128 peak_deallocate(chunk->chunk);
129 peak_deallocate(chunk);
130 }
131 }
132
133 static void
134 __peak_mem_pool_grow(peak_mem_pool pool)
135 {
136 __peak_mem_pool_chunk *h, *p;
137 __peak_mem_pool_entry *e;
138 unsigned int size;
139 unsigned int i;
140
141 pool->_power++;
142 size = 1 << pool->_power;
143
144 #if 0
145 fprintf(stderr, "__peak_mem_pool_grow(%p) -> %d\n", pool, size);
146 #endif
147
148 for (h = pool->_heaphead; h->next != NULL; h = h->next)
149 ;
150
151 p = (__peak_mem_pool_chunk *)peak_allocate(sizeof(__peak_mem_pool_chunk));
152 p->next = NULL;
153 p->chunk =
154 (__peak_mem_pool_entry *)peak_allocate(size * pool->_object_size);
155
156 p->size = size;
157
158 h->next = p;
159
160 e = p->chunk;
161 for (i = 1; i < size; i++, e = e->next)
162 e->next = (__peak_mem_pool_entry *)(((intptr_t)p->chunk)
163 + (size_t)(i * pool->_object_size));
164 e->next = NULL;
165
166 if (pool->_freehead != NULL)
167 e->next = pool->_freehead;
168 pool->_freehead = p->chunk;
169
170 pool->_size += size;
171 }
172
173 void*
174 peak_mem_pool_new(peak_mem_pool pool)
175 {
176 __peak_mem_pool_entry * e = pool->_freehead;
177
178 if (e == NULL)
179 {
180 __peak_mem_pool_grow(pool);
181 e = pool->_freehead;
182 if (e == NULL)
183 PEAK_HALT; /* not cool */
184 }
185 pool->_freehead = pool->_freehead->next;
186 pool->_allocated++;
187 return e;
188 }
189
190 void
191 peak_mem_pool_delete(peak_mem_pool pool, void *ptr)
192 {
193 __peak_mem_pool_entry * e = (__peak_mem_pool_entry *)ptr;
194
195 e->next = pool->_freehead;
196 pool->_freehead = e;
197 pool->_allocated--;
198 }
199
200 int
201 peak_mem_pool_get_used_count(peak_mem_pool pool)
202 {
203 return pool->_allocated;
204 }
205
206 int
207 peak_mem_pool_get_free_count(peak_mem_pool pool)
208 {
209 return pool->_size - pool->_allocated;
210 }
211
212 int
213 peak_mem_pool_get_size(peak_mem_pool pool)
214 {
215 return pool->_size;
216 }