Browse Source

optimize allocation for GNU systems. That is allocate only blocks of a size malloc handles.

1.0.2
Georg Hopp 12 years ago
parent
commit
e905bad981
  1. 139
      src/memory.c

139
src/memory.c

@ -623,65 +623,13 @@ 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))
{
struct memSegment * previous = tree;
struct memSegment * node = tree;
int depth = 1;
int depth = 1;
/*
* I think this has something like O(n+log(n)) on a ballanced
@ -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;
struct memSegment * seg = NULL;
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);

Loading…
Cancel
Save