00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 #include "mempool.h"
00036 #include <stdlib.h>
00037 #include <stdint.h>
00038 #include <string.h>
00039
00040 void
00041 ctrump_mempool_init(struct ctrump_mempool *pool,
00042 unsigned int size_hint)
00043 {
00044 pool->entry_num = 16;
00045 pool->data_entry = malloc(sizeof(unsigned char*)*pool->entry_num);
00046 pool->entry_index = 0;
00047 pool->entry_byte_remain = pool->entry_byte_size = size_hint;
00048 pool->entry_byte_pos = 0;
00049
00050 pool->data_entry[0] = malloc(size_hint);
00051 }
00052
00053 void
00054 ctrump_mempool_destroy(struct ctrump_mempool *pool)
00055 {
00056 int i;
00057 int n = pool->entry_index;
00058 for (i=0; i<=n; i++) {
00059 free(pool->data_entry[i]);
00060 }
00061
00062 free(pool->data_entry);
00063 }
00064
00065
00066 void *
00067 ctrump_mempool_alloc_align(struct ctrump_mempool *pool,
00068 unsigned int align_shift, unsigned int size)
00069 {
00070 uintptr_t ptr, ptr_aligned;
00071 int ptr_diff, remain;
00072 unsigned char *alloc_ptr;
00073 unsigned int align = 1<<align_shift;
00074 uintptr_t align_mask = ~((uintptr_t)(1<<align_shift) - 1);
00075 unsigned int aligned_size = (size + (align-1))&align_mask;
00076 unsigned int alloc_size;
00077
00078 retry:
00079 ptr = (uintptr_t)(pool->data_entry[pool->entry_index] + pool->entry_byte_pos);
00080 ptr_aligned = (ptr+(align-1))&align_mask;
00081 ptr_diff = ptr_aligned - ptr;
00082 remain = pool->entry_byte_remain - ptr_diff;
00083 alloc_ptr = (unsigned char*)ptr_aligned;
00084
00085 if ((int)size > remain) {
00086
00087 unsigned int next_entry_index = pool->entry_index + 1;
00088 alloc_size = pool->entry_byte_size*2;
00089
00090 if ((size+align) > alloc_size)
00091 alloc_size = (size+align)*2;
00092
00093 if (next_entry_index > pool->entry_num) {
00094
00095 int next_entry_num = pool->entry_num * 2;
00096 pool->data_entry = realloc(pool->data_entry, next_entry_num * sizeof(unsigned char*));
00097 pool->entry_num = next_entry_num;
00098 }
00099
00100 pool->entry_byte_remain = pool->entry_byte_size = alloc_size;
00101 pool->entry_index = next_entry_index;
00102 pool->entry_byte_pos = 0;
00103
00104 pool->data_entry[next_entry_index] = malloc(alloc_size);
00105
00106 goto retry;
00107 }
00108
00109 alloc_size = (ptr_diff + aligned_size);
00110
00111 remain -= alloc_size;
00112 pool->entry_byte_remain = remain;
00113 pool->entry_byte_pos += alloc_size;
00114
00115 memset(alloc_ptr, 0x33, size);
00116
00117 return alloc_ptr;
00118 }
00119
00120 char *
00121 ctrump_mempool_strdup(struct ctrump_mempool *p,
00122 char *str)
00123 {
00124 int len = strlen(str);
00125 char *mem = ctrump_mempool_alloc(p, len+1);
00126 memcpy(mem, str, len);
00127 mem[len] = '\0';
00128 return mem;
00129 }