|
|
|
@ -623,58 +623,6 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) |
|
|
|
return del_node; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//static |
|
|
|
//void |
|
|
|
//traverse(struct memSegment * tree, void (*cb)(struct memSegment *, int)) |
|
|
|
//{ |
|
|
|
// struct memSegment * previous = tree; |
|
|
|
// struct memSegment * node = tree; |
|
|
|
// int depth = 1; |
|
|
|
// |
|
|
|
// /* |
|
|
|
// * I think this has something like O(n+log(n)) on a ballanced |
|
|
|
// * tree because I have to traverse back the rightmost leaf to |
|
|
|
// * the root to get a break condition. |
|
|
|
// */ |
|
|
|
// while (node) { |
|
|
|
// /* |
|
|
|
// * If we come from the right so nothing and go to our |
|
|
|
// * next parent. |
|
|
|
// */ |
|
|
|
// if (previous == node->right) { |
|
|
|
// previous = node; |
|
|
|
// node = node->parent; |
|
|
|
// depth--; |
|
|
|
// continue; |
|
|
|
// } |
|
|
|
// |
|
|
|
// if ((NULL == node->left || previous == node->left)) { |
|
|
|
// /* |
|
|
|
// * If there are no more elements to the left or we |
|
|
|
// * came from the left, process data. |
|
|
|
// */ |
|
|
|
// cb(node, depth); |
|
|
|
// previous = node; |
|
|
|
// |
|
|
|
// if (NULL != node->right) { |
|
|
|
// node = node->right; |
|
|
|
// depth++; |
|
|
|
// } else { |
|
|
|
// node = node->parent; |
|
|
|
// depth--; |
|
|
|
// } |
|
|
|
// } else { |
|
|
|
// /* |
|
|
|
// * if there are more elements to the left go there. |
|
|
|
// */ |
|
|
|
// previous = node; |
|
|
|
// node = node->left; |
|
|
|
// depth++; |
|
|
|
// } |
|
|
|
// } |
|
|
|
//} |
|
|
|
|
|
|
|
static |
|
|
|
void |
|
|
|
post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) |
|
|
|
@ -732,42 +680,6 @@ post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//void |
|
|
|
//printElement(struct memSegment * node, int depth) |
|
|
|
//{ |
|
|
|
// int i; |
|
|
|
// |
|
|
|
// printf("%s %010zu:%p(%02d)", |
|
|
|
// (node->color==rbRed)?"R":"B", |
|
|
|
// node->size, |
|
|
|
// node->ptr, |
|
|
|
// depth); |
|
|
|
// for (i=0; i<depth; i++) printf("-"); |
|
|
|
// puts(""); |
|
|
|
// |
|
|
|
// node = node->next; |
|
|
|
// while (NULL != node) { |
|
|
|
// printf(" %s %010zu:%p(%02d)", |
|
|
|
// (node->color==rbRed)?"R":"B", |
|
|
|
// node->size, |
|
|
|
// node->ptr, |
|
|
|
// depth); |
|
|
|
// for (i=0; i<depth; i++) printf("-"); |
|
|
|
// puts(""); |
|
|
|
// node = node->next; |
|
|
|
// } |
|
|
|
//} |
|
|
|
|
|
|
|
//void |
|
|
|
//cleanup(struct memSegment * node, int depth) |
|
|
|
//{ |
|
|
|
// while (NULL != node) { |
|
|
|
// struct memSegment * next = node->next; |
|
|
|
// free(node); |
|
|
|
// node = next; |
|
|
|
// } |
|
|
|
//} |
|
|
|
|
|
|
|
static |
|
|
|
struct memSegment * segments = NULL; |
|
|
|
|
|
|
|
@ -793,20 +705,55 @@ TR_reference(void * mem) |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* This will always allocate a multiple of PAGESIZE |
|
|
|
* This tries to reflect the memory management behaviour of the |
|
|
|
* GNU version of malloc. For other versions this might need |
|
|
|
* to be changed to be optimal. |
|
|
|
* |
|
|
|
* However, GNU malloc keeps separate pools for each power of |
|
|
|
* 2 memory size up to page size. So one page consists all of |
|
|
|
* memory blocks of the same sizei (a power of 2). |
|
|
|
* |
|
|
|
* Also as far as I understand the smallest allocatable block is |
|
|
|
* 8 bytes. At least the adresses are alwayse a multiple of 8. |
|
|
|
* |
|
|
|
* So lets say page size is 4096. There is nothing allocated |
|
|
|
* right now. We allocate a block of 8 bytes. This will request |
|
|
|
* a memory page from the OS. Then define it as a page containing |
|
|
|
* 8 byte blocks and return the address of the first one of these. |
|
|
|
* Any subsequent call to malloc for 8 bytes will return one of the |
|
|
|
* blocks within this page as long as there are some left. |
|
|
|
* |
|
|
|
* So what we do here is up to page size round the request size up |
|
|
|
* to the next power of 2 >= 8. |
|
|
|
* Sizes greater then pagesize will be round up to the next |
|
|
|
* multiple of pagesize. As far as I understand these are not |
|
|
|
* pooled anyway. |
|
|
|
* |
|
|
|
* For now this assumes we are on a little endian machine. |
|
|
|
*/ |
|
|
|
void * |
|
|
|
TR_malloc(size_t size) |
|
|
|
{ |
|
|
|
struct memSegment * seg = NULL; |
|
|
|
//long psize = sysconf(_SC_PAGESIZE); |
|
|
|
long psize = 64; |
|
|
|
long psize = sysconf(_SC_PAGESIZE); |
|
|
|
size_t check; |
|
|
|
|
|
|
|
size += sizeof(struct memSegment); |
|
|
|
|
|
|
|
/* allocate only blocks of a multiple of pagesize, similar to cbuf */ |
|
|
|
size = (0>=size)?1:(0!=size%psize)?(size/psize)+1:size/psize; |
|
|
|
size *= psize; |
|
|
|
if (size > psize) { |
|
|
|
if (0 != (size % psize)) { |
|
|
|
// size if not a multiple of pagesize so bring it to one. |
|
|
|
size = ((size / psize) + 1) * psize; |
|
|
|
} |
|
|
|
} else { |
|
|
|
check = size >> 1; |
|
|
|
check = (size | check) - check; |
|
|
|
|
|
|
|
if (check != size) { |
|
|
|
// size is not a power of 2 so bring it to one. |
|
|
|
size = ((size << 1) | size) - size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef MEM_OPT |
|
|
|
seg = findElement(segments, size); |
|
|
|
|