00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include "gspin-tree.h"
00027 #include "gspin-mempool.h"
00028
00029
00030 #if 0 // this version for testing
00031 #define GS_MEMBLOCK_SIZE 0x1000 // must be power of 2 and multiple of
00032
00033
00034 #define GS_BLOCK_IDX_SHIFT_AMT 12
00035 #define GS_OFST_IN_BLK_MASK 0xfff
00036 #else
00037 #define GS_MEMBLOCK_SIZE 0x1000000// must be power of 2 and multiple of
00038
00039
00040 #define GS_BLOCK_IDX_SHIFT_AMT 24
00041 #define GS_OFST_IN_BLK_MASK 0xffffff
00042 #endif
00043
00044 gs_arena_t gs_mempool[GS_ARENA_COUNT] = {
00045
00046 { NULL, NULL, 0 },
00047 { NULL, NULL, 0 },
00048
00049 };
00050
00051
00052 gs_memblock_t *gs_new_memblock(int id)
00053 {
00054 gs_memblock_t *memblk = (gs_memblock_t *)malloc(sizeof(gs_memblock_t));
00055 memblk->block_id = id;
00056 memblk->mem = (char *)calloc(GS_MEMBLOCK_SIZE, 1);
00057 if (memblk->mem == NULL)
00058 fprintf(stderr, "Out of memory.\n");
00059 memblk->next = NULL;
00060 return memblk;
00061 }
00062
00063
00064 void *__gs_mempool_alloc(unsigned int arena_id, unsigned int count)
00065 {
00066 gs_arena_t *arena = &gs_mempool[arena_id];
00067 gs_memblock_t *memblk = arena->lastblock;
00068 if (memblk == NULL) {
00069 memblk = gs_new_memblock(0);
00070 arena->firstblock = arena->lastblock = memblk;
00071 arena->current_index = 0;
00072 }
00073 else if ((arena->current_index + count - 1) >=
00074 ((memblk->block_id + 1) << GS_BLOCK_IDX_SHIFT_AMT)) {
00075 memblk = gs_new_memblock(memblk->block_id + 1);
00076 arena->lastblock->next = memblk;
00077 arena->lastblock = memblk;
00078 if (count > 1)
00079 arena->current_index = memblk->block_id * GS_MEMBLOCK_SIZE;
00080 }
00081 gs_void_t *p = &memblk->mem[arena->current_index & GS_OFST_IN_BLK_MASK];
00082 arena->current_index += count;
00083 return p;
00084 }
00085
00086 static gs_memblock_t *memblk_cache[GS_ARENA_COUNT] = {NULL, NULL};
00087
00088
00089 gs_void_t *gs_mempool_idx2address(int arena_id, int cell_index)
00090 {
00091 gs_arena_t *arena = &gs_mempool[arena_id];
00092 int cur_block_id = cell_index >> GS_BLOCK_IDX_SHIFT_AMT;
00093 if (memblk_cache[arena_id] == NULL || memblk_cache[arena_id]->block_id > cur_block_id)
00094 memblk_cache[arena_id] = arena->firstblock;
00095 while (memblk_cache[arena_id]->block_id != cur_block_id)
00096 memblk_cache[arena_id] = memblk_cache[arena_id]->next;
00097 int block_byte_ofst = cell_index & GS_OFST_IN_BLK_MASK;
00098 return memblk_cache[arena_id]->mem + block_byte_ofst;
00099 }
00100
00101 extern char *mem_seg;
00102
00103
00104
00105
00106
00107
00108
00109
00110 long gs_mempool_address2byteofst(int arena_id, char *p) {
00111 if (memblk_cache[arena_id] == NULL ||
00112 !(p >= memblk_cache[arena_id]->mem &&
00113 p - memblk_cache[arena_id]->mem < GS_MEMBLOCK_SIZE)) {
00114 memblk_cache[arena_id] = gs_mempool[arena_id].firstblock;
00115
00116 }
00117 while (memblk_cache[arena_id] != NULL &&
00118 !(p >= memblk_cache[arena_id]->mem &&
00119 p - memblk_cache[arena_id]->mem < GS_MEMBLOCK_SIZE))
00120 memblk_cache[arena_id] = memblk_cache[arena_id]->next;
00121 if (memblk_cache[arena_id] != NULL)
00122 return memblk_cache[arena_id]->block_id * GS_MEMBLOCK_SIZE + p - memblk_cache[arena_id]->mem;
00123
00124 GS_ASSERT(arena_id == GS_ARENA, "gs_mempool_address2byteofst failure");
00125 return p - mem_seg;
00126 }