Browse Source

now valgrind shows no more violations...but cleanup does not work correcly. The memory usage depends now on the amount of paralell connections...ab show approximately 10% to 20% performance improvement / and the code is far from optimal.

release0.1.5
Georg Hopp 12 years ago
parent
commit
157f48031c
  1. 248
      src/rbtree.c
  2. 2
      src/taskrambler.c
  3. 255
      src/utils/memory.c

248
src/rbtree.c

@ -14,6 +14,9 @@ struct element
enum rbColor color;
struct element * next;
struct element * last;
struct element * parent;
struct element * left;
struct element * right;
@ -27,6 +30,9 @@ newElement(size_t size)
element->size = size;
element->ptr = element + sizeof(struct element);
element->next = NULL;
element->last = NULL;
element->color = rbRed;
element->parent = NULL;
element->left = NULL;
@ -192,17 +198,21 @@ insertElement(struct element ** tree, struct element * element)
struct element * u;
struct element * g;
element->next = NULL;
element->last = NULL;
element->color = rbRed;
element->parent = NULL;
element->left = NULL;
element->right = NULL;
// if tree is empty it's simple... :)
if (NULL == node) {
*tree = node = new_node = element;
} else {
// normal binary tree add....
while (element->size != node->size || element->ptr != node->ptr) {
if (element->size < node->size && NULL != node->left) {
node = node->left;
} else if (element->size > node->size && NULL != node->right) {
node = node->right;
} else if (element->ptr < node->ptr) {
while (NULL != node) {
if (element->size < node->size) {
if (NULL == node->left) {
node->left = element;
node->left->parent = node;
@ -211,7 +221,7 @@ insertElement(struct element ** tree, struct element * element)
} else {
node = node->left;
}
} else if (element->ptr > node->ptr) {
} else if (element->size > node->size) {
if (NULL == node->right) {
node->right = element;
node->right->parent = node;
@ -221,6 +231,13 @@ insertElement(struct element ** tree, struct element * element)
node = node->right;
}
} else {
if (NULL == node->next) {
node->next = element;
node->last = element;
} else {
node->last->next = element;
node->last = element;
}
return node;
}
}
@ -327,14 +344,41 @@ deleteElement(struct element ** tree, struct element * element)
struct element * s;
// find the relevant node and it's parent
while (NULL != node
&& node->size != element->size
&& node->ptr != element->ptr) {
while (NULL != node) {
if (element->size < node->size || element->ptr < node->ptr) {
if (element->size < node->size) {
node = node->left;
} else {
} else if (element->size > node->size) {
node = node->right;
} else {
if (NULL != node->next) {
if (NULL != node->parent) {
if (node == node->parent->left) {
node->parent->left = node->next;
} else {
node->parent->right = node->next;
}
} else {
*tree = node->next;
}
if (NULL != node->left) {
node->left->parent = node->next;
}
if (NULL != node->right) {
node->right->parent = node->next;
}
node->next->last = node->last;
node->next->color = node->color;
node->next->parent = node->parent;
node->next->left = node->left;
node->next->right = node->right;
return node;
}
break;
}
}
@ -521,7 +565,7 @@ deleteElement(struct element ** tree, struct element * element)
void
traverse(struct element * tree, void (*cb)(size_t, void *, int, enum rbColor))
traverse(struct element * tree, void (*cb)(struct element *, int))
{
struct element * previous = tree;
struct element * node = tree;
@ -549,7 +593,62 @@ traverse(struct element * tree, void (*cb)(size_t, void *, int, enum rbColor))
* If there are no more elements to the left or we
* came from the left, process data.
*/
cb(node->size, node->ptr, depth, node->color);
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++;
}
}
}
void
post(struct element * tree, void (*cb)(struct element *, int))
{
struct element * previous = tree;
struct element * 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 ((NULL == node->left && NULL == node->right)
|| previous == node->right) {
struct element * parent = node->parent;
cb(node, depth);
previous = 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.
*/
previous = node;
if (NULL != node->right) {
@ -570,15 +669,41 @@ traverse(struct element * tree, void (*cb)(size_t, void *, int, enum rbColor))
}
}
void printElement(size_t size, void * ptr, int depth, enum rbColor color)
void printElement(struct element * node, int depth)
{
int i;
printf("%s %010zu:0x%p(%02d)", (color==rbRed)?"R":"B", size, ptr, depth);
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 element * node, int depth)
{
while (NULL != node) {
printf("free node: ");
printElement(node, 0);
struct element * next = node->next;
free(node);
node = next;
}
}
/**
* =======================================================================
@ -588,58 +713,6 @@ main(int argc, char * argv[])
{
struct element * root = NULL;
struct element * found = NULL;
int value;
int count;
// insertElement(&root, newElement(84));
// insertElement(&root, newElement(87));
// insertElement(&root, newElement(78));
// insertElement(&root, newElement(16));
// insertElement(&root, newElement(94));
//
// puts("traverse");
// traverse(root, printElement);
//
// free(deleteElement(&root, findElement(root, 87)));
// puts("traverse");
// traverse(root, printElement);
// free(deleteElement(&root, findElement(root, 94)));
// puts("traverse");
// traverse(root, printElement);
// free(deleteElement(&root, findElement(root, 16)));
// puts("traverse");
// traverse(root, printElement);
// free(deleteElement(&root, findElement(root, 84)));
// puts("traverse");
// traverse(root, printElement);
// free(deleteElement(&root, findElement(root, 78)));
// puts("traverse");
// traverse(root, printElement);
//
// for (count=0; count<NVALUES;) {
// value = (random() % 1000000) + 1;
//
// if (NULL == findElement(root, value)) {
// insertElement(&root, newElement(value));
// count++;
// }
// }
//
// puts("traverse");
// traverse(root, printElement);
//
// for (count=0; count<NVALUES;) {
// value = (random() % 1000000) + 1;
// struct element * element = findElement(root, value);
//
// if (NULL != element) {
// free(deleteElement(&root, element));
// count++;
// }
// }
//
// puts("traverse");
// traverse(root, printElement);
insertElement(&root, newElement(40));
insertElement(&root, newElement(50));
@ -662,7 +735,7 @@ main(int argc, char * argv[])
if (NULL == found) {
printf("can't find segmenet of minimum size: %d\n", 10);
} else {
printElement(found->size, found->ptr, 0, found->color);
printElement(found, 0);
}
puts("");
@ -670,7 +743,7 @@ main(int argc, char * argv[])
if (NULL == found) {
printf("can't find segmenet of minimum size: %d\n", 64);
} else {
printElement(found->size, found->ptr, 0, found->color);
printElement(found, 0);
}
puts("");
@ -678,15 +751,46 @@ main(int argc, char * argv[])
if (NULL == found) {
printf("can't find segmenet of minimum size: %d\n", 90);
} else {
printElement(found->size, found->ptr, 0, found->color);
printElement(found, 0);
}
puts("");
deleteElement(&root, findElement(root, 70));
free(deleteElement(&root, findElement(root, 70)));
puts("traverse");
traverse(root, printElement);
puts("");
insertElement(&root, newElement(80));
insertElement(&root, newElement(50));
insertElement(&root, newElement(80));
puts("traverse");
traverse(root, printElement);
puts("");
found = deleteElement(&root, findElement(root, 80));
printf("up to free: %p\n", found);
free(found);
puts("traverse");
traverse(root, printElement);
puts("");
found = deleteElement(&root, findElement(root, 50));
printf("up to free: %p\n", found);
free(found);
puts("traverse");
traverse(root, printElement);
puts("");
found = deleteElement(&root, findElement(root, 70));
printf("up to free: %p\n", found);
free(found);
puts("traverse");
traverse(root, printElement);
puts("");
post(root, cleanup);
return 0;
}

2
src/taskrambler.c

@ -72,7 +72,7 @@ main()
setrlimit(RLIMIT_NOFILE, &limit);
init_signals();
daemonize();
//daemonize();
shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU);
if (-1 == ftruncate(shm, psize)) {

255
src/utils/memory.c

@ -56,18 +56,17 @@
enum rbColor {rbBlack=1, rbRed=2};
int malloccount = 0;
struct memSegment {
size_t size;
void * ptr;
// for address queue
struct memSegment * next;
struct memSegment * last;
struct memSegment
{
size_t size;
void * ptr;
// for rbtree
enum rbColor color;
struct memSegment * next;
struct memSegment * last;
struct memSegment * parent;
struct memSegment * left;
struct memSegment * right;
@ -77,14 +76,12 @@ struct memSegment *
newElement(size_t size)
{
struct memSegment * element = malloc(size + sizeof(struct memSegment));
malloccount++;
printf("+");
element->size = size;
element->ptr = (void *)element + sizeof(struct memSegment);
element->ptr = (void*)element + sizeof(struct memSegment);
element->next = NULL;
element->last = NULL;
element->next = NULL;
element->last = NULL;
element->color = rbRed;
element->parent = NULL;
@ -104,7 +101,7 @@ findElement(struct memSegment * tree, size_t size)
while (NULL != tree) {
if (tree->size == size) {
fitting = tree;
fitting = tree;
break;
}
@ -251,19 +248,20 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
struct memSegment * u;
struct memSegment * g;
element->color = rbRed;
element->parent = NULL;
element->left = NULL;
element->right = NULL;
element->next = NULL;
element->last = NULL;
element->next = NULL;
element->last = NULL;
element->color = rbRed;
element->parent = NULL;
element->left = NULL;
element->right = NULL;
// if tree is empty it's simple... :)
if (NULL == node) {
*tree = node = new_node = element;
} else {
// normal binary tree add....
while (element->size != node->size) {
while (NULL != node) {
if (element->size < node->size) {
if (NULL == node->left) {
node->left = element;
@ -283,13 +281,14 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
node = node->right;
}
} else {
if (NULL == node->next) {
node->next = node->last = element;
} else {
node->last->next = element;
node->last = element;
}
return element;
if (NULL == node->next) {
node->next = element;
node->last = element;
} else {
node->last->next = element;
node->last = element;
}
return node;
}
}
}
@ -365,6 +364,12 @@ insertElement(struct memSegment ** tree, struct memSegment * element)
* aka left in-order successor.
* We return the parent of the element in the out argument parent.
* This can be NULL wenn calling.
*
* 2: *successor = {size = 80, ptr = 0x603ae0, color = rbRed, parent = 0x603160,
* left = 0x0, right = 0x0}
* 1: *node = {size = 70, ptr = 0x603a60, color = rbBlack, parent = 0x603070,
* left = 0x6030e0, right = 0x6031e0}
*
*/
struct memSegment *
findInOrderSuccessor(struct memSegment * tree)
@ -390,46 +395,41 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
// find the relevant node and it's parent
while (NULL != node) {
if (element->size < node->size) {
node = node->left;
} else if (element->size > node->size) {
node = node->right;
} else {
// we know we found our tree element.
if (NULL != node->next) {
// last element.
if (NULL != node->parent) {
if (node->parent->left == node->parent) {
node->parent->left = node->next;
} else {
node->parent->right = node->next;
}
}
if (NULL != node->left) {
node->left->parent = node->next;
}
if (NULL != node->right) {
node->right->parent = node->next;
}
if (node->next == node->last) {
node->next->next = NULL;
node->next->last = NULL;
} else {
node->next->last = node->last;
}
node->next->parent = node->parent;
node->next->color = node->color;
node->next->left = node->left;
node->next->right = node->right;
return node;
}
break;
}
if (NULL != node->next) {
if (NULL != node->parent) {
if (node == node->parent->left) {
node->parent->left = node->next;
} else {
node->parent->right = node->next;
}
} else {
*tree = node->next;
}
if (NULL != node->left) {
node->left->parent = node->next;
}
if (NULL != node->right) {
node->right->parent = node->next;
}
node->next->last = node->last;
node->next->color = node->color;
node->next->parent = node->parent;
node->next->left = node->left;
node->next->right = node->right;
return node;
}
break;
}
}
// element not found
@ -446,10 +446,6 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
if (NULL != node->left && NULL != node->right) {
struct memSegment * successor = findInOrderSuccessor(node);
// this is a replacement code for simply change value and remove
// successor...I can not do this here because the address of
// the object is part of the information that has to be
// preserved.
enum rbColor tmpcolor = successor->color;
struct memSegment * tmpparent = successor->parent;
struct memSegment * tmpleft = successor->left;
@ -630,7 +626,7 @@ traverse(struct memSegment * tree, void (*cb)(struct memSegment *, int))
* tree because I have to traverse back the rightmost leaf to
* the root to get a break condition.
*/
while (NULL != node) {
while (node) {
/*
* If we come from the right so nothing and go to our
* next parent.
@ -668,20 +664,95 @@ traverse(struct memSegment * tree, void (*cb)(struct memSegment *, int))
}
}
void
post(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 ((NULL == node->left && NULL == node->right)
|| previous == node->right) {
struct memSegment * parent = node->parent;
cb(node, depth);
previous = 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.
*/
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++;
}
}
}
void printElement(struct memSegment * node, int depth)
{
int i;
printf("%s %010zu:0x%p(%02d)",
(node->color==rbRed)?"R":"B",
node->size,
node->ptr,
depth);
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;
}
}
struct memSegment * segments = NULL;
@ -731,13 +802,11 @@ static
void
segmentFree(struct memSegment * segment, int depth)
{
while (NULL != segment) {
struct memSegment * next = segment->next;
free(segment);
malloccount--;
printf("-");
segment = next;
}
while (NULL != segment) {
struct memSegment * next = segment->next;
free(segment);
segment = next;
}
}
@ -757,7 +826,7 @@ memMalloc(size_t size)
} else {
//printf(" FOUND Segment: 0x%p of size: %zu\n", seg, seg->size);
// remove the found one from the tree as we use it now.
deleteElement(&segments, seg);
seg = deleteElement(&segments, seg);
}
@ -798,28 +867,10 @@ memFree(void ** mem)
}
}
void
pre_order(struct memSegment * tree, void (*cb)(struct memSegment *, int))
{
if (NULL != tree) {
if (NULL != tree->left) {
pre_order(tree->left, cb);
}
if (NULL != tree->right) {
pre_order(tree->right, cb);
}
cb(tree, 0);
}
}
void
memCleanup()
{
printf("\n");
pre_order(segments, segmentFree);
printf("\nmalloccount: %d\n", malloccount);
post(segments, segmentFree);
}
void

Loading…
Cancel
Save