00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "memorypool.h"
00026
00027
00028 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
00029 #define MAP_ANONYMOUS MAP_ANON
00030 #endif
00031 #ifndef MAP_FAILED
00032 #define MAP_FAILED ((void*)-1)
00033 #endif
00034
00038 #define ALIGN_SIZE (2 * sizeof(void*))
00039
00043 #define ROUND_TO_ALIGN(n) ((n+(ALIGN_SIZE-1)) & (~(ALIGN_SIZE-1)))
00044
00045
00050 struct MemoryPool
00051 {
00052
00056 char *memory;
00057
00061 size_t size;
00062
00066 size_t pos;
00067
00071 size_t end;
00072
00076 int is_mmap;
00077 };
00078
00079
00086 struct MemoryPool *
00087 MHD_pool_create (size_t max)
00088 {
00089 struct MemoryPool *pool;
00090
00091 pool = malloc (sizeof (struct MemoryPool));
00092 if (NULL == pool)
00093 return NULL;
00094 #ifdef MAP_ANONYMOUS
00095 if (max <= 32 * 1024)
00096 pool->memory = MAP_FAILED;
00097 else
00098 pool->memory = MMAP (NULL, max, PROT_READ | PROT_WRITE,
00099 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
00100 #else
00101 pool->memory = MAP_FAILED;
00102 #endif
00103 if ((pool->memory == MAP_FAILED) || (pool->memory == NULL))
00104 {
00105 pool->memory = malloc (max);
00106 if (pool->memory == NULL)
00107 {
00108 free (pool);
00109 return NULL;
00110 }
00111 pool->is_mmap = MHD_NO;
00112 }
00113 else
00114 {
00115 pool->is_mmap = MHD_YES;
00116 }
00117 pool->pos = 0;
00118 pool->end = max;
00119 pool->size = max;
00120 return pool;
00121 }
00122
00123
00129 void
00130 MHD_pool_destroy (struct MemoryPool *pool)
00131 {
00132 if (pool == NULL)
00133 return;
00134 if (pool->is_mmap == MHD_NO)
00135 free (pool->memory);
00136 else
00137 MUNMAP (pool->memory, pool->size);
00138 free (pool);
00139 }
00140
00141
00153 void *
00154 MHD_pool_allocate (struct MemoryPool *pool,
00155 size_t size, int from_end)
00156 {
00157 void *ret;
00158 size_t asize;
00159
00160 asize = ROUND_TO_ALIGN (size);
00161 if ( (0 == asize) && (0 != size) )
00162 return NULL;
00163 if ((pool->pos + asize > pool->end) || (pool->pos + asize < pool->pos))
00164 return NULL;
00165 if (from_end == MHD_YES)
00166 {
00167 ret = &pool->memory[pool->end - asize];
00168 pool->end -= asize;
00169 }
00170 else
00171 {
00172 ret = &pool->memory[pool->pos];
00173 pool->pos += asize;
00174 }
00175 return ret;
00176 }
00177
00178
00196 void *
00197 MHD_pool_reallocate (struct MemoryPool *pool,
00198 void *old,
00199 size_t old_size,
00200 size_t new_size)
00201 {
00202 void *ret;
00203 size_t asize;
00204
00205 asize = ROUND_TO_ALIGN (new_size);
00206 if ( (0 == asize) && (0 != new_size) )
00207 return NULL;
00208 if ((pool->end < old_size) || (pool->end < asize))
00209 return NULL;
00210
00211 if ((pool->pos >= old_size) && (&pool->memory[pool->pos - old_size] == old))
00212 {
00213
00214 if (pool->pos + asize - old_size <= pool->end)
00215 {
00216
00217 pool->pos += asize - old_size;
00218 if (asize < old_size)
00219 memset (&pool->memory[pool->pos], 0, old_size - asize);
00220 return old;
00221 }
00222
00223 return NULL;
00224 }
00225 if (asize <= old_size)
00226 return old;
00227 if ((pool->pos + asize >= pool->pos) &&
00228 (pool->pos + asize <= pool->end))
00229 {
00230
00231 ret = &pool->memory[pool->pos];
00232 memcpy (ret, old, old_size);
00233 pool->pos += asize;
00234 return ret;
00235 }
00236
00237 return NULL;
00238 }
00239
00240
00250 void *
00251 MHD_pool_reset (struct MemoryPool *pool,
00252 void *keep,
00253 size_t size)
00254 {
00255 size = ROUND_TO_ALIGN (size);
00256 if (NULL != keep)
00257 {
00258 if (keep != pool->memory)
00259 {
00260 memmove (pool->memory, keep, size);
00261 keep = pool->memory;
00262 }
00263 pool->pos = size;
00264 }
00265 pool->end = pool->size;
00266 memset (&pool->memory[size],
00267 0,
00268 pool->size - size);
00269 return keep;
00270 }
00271
00272
00273