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 }