memorypool.c
Go to the documentation of this file.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 struct MemoryPool
00046 {
00047
00051 char *memory;
00052
00056 size_t size;
00057
00061 size_t pos;
00062
00066 size_t end;
00067
00071 int is_mmap;
00072 };
00073
00079 struct MemoryPool *
00080 MHD_pool_create (size_t max)
00081 {
00082 struct MemoryPool *pool;
00083
00084 pool = malloc (sizeof (struct MemoryPool));
00085 if (pool == NULL)
00086 return NULL;
00087 #ifdef MAP_ANONYMOUS
00088 pool->memory = MMAP (NULL, max, PROT_READ | PROT_WRITE,
00089 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
00090 #else
00091 pool->memory = MAP_FAILED;
00092 #endif
00093 if ((pool->memory == MAP_FAILED) || (pool->memory == NULL))
00094 {
00095 pool->memory = malloc (max);
00096 if (pool->memory == NULL)
00097 {
00098 free (pool);
00099 return NULL;
00100 }
00101 pool->is_mmap = MHD_NO;
00102 }
00103 else
00104 {
00105 pool->is_mmap = MHD_YES;
00106 }
00107 pool->pos = 0;
00108 pool->end = max;
00109 pool->size = max;
00110 return pool;
00111 }
00112
00116 void
00117 MHD_pool_destroy (struct MemoryPool *pool)
00118 {
00119 if (pool == NULL)
00120 return;
00121 if (pool->is_mmap == MHD_NO)
00122 free (pool->memory);
00123 else
00124 MUNMAP (pool->memory, pool->size);
00125 free (pool);
00126 }
00127
00133 void *
00134 MHD_pool_allocate (struct MemoryPool *pool,
00135 size_t size, int from_end)
00136 {
00137 void *ret;
00138
00139 size = ROUND_TO_ALIGN (size);
00140 if ((pool->pos + size > pool->end) || (pool->pos + size < pool->pos))
00141 return NULL;
00142 if (from_end == MHD_YES)
00143 {
00144 ret = &pool->memory[pool->end - size];
00145 pool->end -= size;
00146 }
00147 else
00148 {
00149 ret = &pool->memory[pool->pos];
00150 pool->pos += size;
00151 }
00152 return ret;
00153 }
00154
00171 void *
00172 MHD_pool_reallocate (struct MemoryPool *pool,
00173 void *old,
00174 size_t old_size,
00175 size_t new_size)
00176 {
00177 void *ret;
00178
00179 new_size = ROUND_TO_ALIGN (new_size);
00180 if ((pool->end < old_size) || (pool->end < new_size))
00181 return NULL;
00182
00183 if ((pool->pos >= old_size) && (&pool->memory[pool->pos - old_size] == old))
00184 {
00185
00186 if (pool->pos + new_size - old_size <= pool->end)
00187 {
00188
00189 pool->pos += new_size - old_size;
00190 if (new_size < old_size)
00191 memset (&pool->memory[pool->pos], 0, old_size - new_size);
00192 return old;
00193 }
00194
00195 return NULL;
00196 }
00197 if (new_size <= old_size)
00198 return old;
00199 if ((pool->pos + new_size >= pool->pos) &&
00200 (pool->pos + new_size <= pool->end))
00201 {
00202
00203 ret = &pool->memory[pool->pos];
00204 memcpy (ret, old, old_size);
00205 pool->pos += new_size;
00206 return ret;
00207 }
00208
00209 return NULL;
00210 }
00211
00220 void *
00221 MHD_pool_reset (struct MemoryPool *pool,
00222 void *keep,
00223 size_t size)
00224 {
00225 size = ROUND_TO_ALIGN (size);
00226 if (keep != NULL)
00227 {
00228 if (keep != pool->memory)
00229 {
00230 memmove (pool->memory, keep, size);
00231 keep = pool->memory;
00232 }
00233 pool->pos = size;
00234 }
00235 pool->end = pool->size;
00236 return keep;
00237 }
00238
00239
00240
00241