Commit e905bad9816b19fa0004a54d2cda7ba840ca6b93
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