Commit e905bad9816b19fa0004a54d2cda7ba840ca6b93

Authored by Georg Hopp
1 parent 0c2907f9

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

Showing 1 changed file with 43 additions and 96 deletions
... ... @@ -623,65 +623,13 @@ deleteElement(struct memSegment ** tree, struct memSegment * element)
623 623 return del_node;
624 624 }
625 625
626   -
627   -//static
628   -//void
629   -//traverse(struct memSegment * tree, void (*cb)(struct memSegment *, int))
630   -//{
631   -// struct memSegment * previous = tree;
632   -// struct memSegment * node = tree;
633   -// int depth = 1;
634   -//
635   -// /*
636   -// * I think this has something like O(n+log(n)) on a ballanced
637   -// * tree because I have to traverse back the rightmost leaf to
638   -// * the root to get a break condition.
639   -// */
640   -// while (node) {
641   -// /*
642   -// * If we come from the right so nothing and go to our
643   -// * next parent.
644   -// */
645   -// if (previous == node->right) {
646   -// previous = node;
647   -// node = node->parent;
648   -// depth--;
649   -// continue;
650   -// }
651   -//
652   -// if ((NULL == node->left || previous == node->left)) {
653   -// /*
654   -// * If there are no more elements to the left or we
655   -// * came from the left, process data.
656   -// */
657   -// cb(node, depth);
658   -// previous = node;
659   -//
660   -// if (NULL != node->right) {
661   -// node = node->right;
662   -// depth++;
663   -// } else {
664   -// node = node->parent;
665   -// depth--;
666   -// }
667   -// } else {
668   -// /*
669   -// * if there are more elements to the left go there.
670   -// */
671   -// previous = node;
672   -// node = node->left;
673   -// depth++;
674   -// }
675   -// }
676   -//}
677   -
678 626 static
679 627 void
680 628 post(struct memSegment * tree, void (*cb)(struct memSegment *, int))
681 629 {
682 630 struct memSegment * previous = tree;
683 631 struct memSegment * node = tree;
684   - int depth = 1;
  632 + int depth = 1;
685 633
686 634 /*
687 635 * 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))
732 680 }
733 681 }
734 682
735   -//void
736   -//printElement(struct memSegment * node, int depth)
737   -//{
738   -// int i;
739   -//
740   -// printf("%s %010zu:%p(%02d)",
741   -// (node->color==rbRed)?"R":"B",
742   -// node->size,
743   -// node->ptr,
744   -// depth);
745   -// for (i=0; i<depth; i++) printf("-");
746   -// puts("");
747   -//
748   -// node = node->next;
749   -// while (NULL != node) {
750   -// printf(" %s %010zu:%p(%02d)",
751   -// (node->color==rbRed)?"R":"B",
752   -// node->size,
753   -// node->ptr,
754   -// depth);
755   -// for (i=0; i<depth; i++) printf("-");
756   -// puts("");
757   -// node = node->next;
758   -// }
759   -//}
760   -
761   -//void
762   -//cleanup(struct memSegment * node, int depth)
763   -//{
764   -// while (NULL != node) {
765   -// struct memSegment * next = node->next;
766   -// free(node);
767   -// node = next;
768   -// }
769   -//}
770   -
771 683 static
772 684 struct memSegment * segments = NULL;
773 685
... ... @@ -793,20 +705,55 @@ TR_reference(void * mem)
793 705 }
794 706
795 707 /*
796   - * This will always allocate a multiple of PAGESIZE
  708 + * This tries to reflect the memory management behaviour of the
  709 + * GNU version of malloc. For other versions this might need
  710 + * to be changed to be optimal.
  711 + *
  712 + * However, GNU malloc keeps separate pools for each power of
  713 + * 2 memory size up to page size. So one page consists all of
  714 + * memory blocks of the same sizei (a power of 2).
  715 + *
  716 + * Also as far as I understand the smallest allocatable block is
  717 + * 8 bytes. At least the adresses are alwayse a multiple of 8.
  718 + *
  719 + * So lets say page size is 4096. There is nothing allocated
  720 + * right now. We allocate a block of 8 bytes. This will request
  721 + * a memory page from the OS. Then define it as a page containing
  722 + * 8 byte blocks and return the address of the first one of these.
  723 + * Any subsequent call to malloc for 8 bytes will return one of the
  724 + * blocks within this page as long as there are some left.
  725 + *
  726 + * So what we do here is up to page size round the request size up
  727 + * to the next power of 2 >= 8.
  728 + * Sizes greater then pagesize will be round up to the next
  729 + * multiple of pagesize. As far as I understand these are not
  730 + * pooled anyway.
  731 + *
  732 + * For now this assumes we are on a little endian machine.
797 733 */
798 734 void *
799 735 TR_malloc(size_t size)
800 736 {
801   - struct memSegment * seg = NULL;
802   - //long psize = sysconf(_SC_PAGESIZE);
803   - long psize = 64;
  737 + struct memSegment * seg = NULL;
  738 + long psize = sysconf(_SC_PAGESIZE);
  739 + size_t check;
804 740
805 741 size += sizeof(struct memSegment);
806 742
807   - /* allocate only blocks of a multiple of pagesize, similar to cbuf */
808   - size = (0>=size)?1:(0!=size%psize)?(size/psize)+1:size/psize;
809   - size *= psize;
  743 + if (size > psize) {
  744 + if (0 != (size % psize)) {
  745 + // size if not a multiple of pagesize so bring it to one.
  746 + size = ((size / psize) + 1) * psize;
  747 + }
  748 + } else {
  749 + check = size >> 1;
  750 + check = (size | check) - check;
  751 +
  752 + if (check != size) {
  753 + // size is not a power of 2 so bring it to one.
  754 + size = ((size << 1) | size) - size;
  755 + }
  756 + }
810 757
811 758 #ifdef MEM_OPT
812 759 seg = findElement(segments, size);
... ...
Please register or login to post a comment