/* type = heap->heapinfo[block].type; */
/* switch(type){ */
- /* case -1 : /\* Free block *\/ */
+ /* case MMALLOC_TYPE_HEAPINFO : */
+ /* case MMALLOC_TYPE_FREE : /\* Free block *\/ */
/* fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n"); */
/* xbt_abort(); */
/* break; */
malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i1], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
- if (heapinfo1->type == -1) { /* Free block */
- i1++;
+ if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) { /* Free block */
+ i1 += heapinfo1->free_block.size;
continue;
}
+ if (heapinfo1->type < 0) {
+ fprintf(stderr, "Unkown mmalloc block type.\n");
+ abort();
+ }
+
addr_block1 =
((void *) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE +
(char *) ((xbt_mheap_t) state->s_heap)->heapbase));
- if (heapinfo1->type == 0) { /* Large block */
+ if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */
if (is_stack(addr_block1)) {
for (k = 0; k < heapinfo1->busy_block.size; k++)
malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
- if (heapinfo2b->type != 0) {
+ if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) {
i2++;
continue;
}
while (i2 <= state->heaplimit && !equal) {
malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
- if (heapinfo2b->type <= 0) {
- i2++;
+
+ if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) {
+ i2 += heapinfo2b->free_block.size;
continue;
}
+ if (heapinfo2b->type < 0) {
+ fprintf(stderr, "Unkown mmalloc block type.\n");
+ abort();
+ }
+
for (j2 = 0; j2 < (size_t) (BLOCKSIZE >> heapinfo2b->type);
j2++) {
for(i = 1; i <= state->heaplimit; i++) {
malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
- if (heapinfo1->type == 0) {
+ if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) {
if (i1 == state->heaplimit) {
if (heapinfo1->busy_block.busy_size > 0) {
if (state->equals_to1_(i, 0).valid == 0) {
for (i=1; i <= state->heaplimit; i++) {
malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
- if (heapinfo2->type == 0) {
+ if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) {
if (i1 == state->heaplimit) {
if (heapinfo2->busy_block.busy_size > 0) {
if (state->equals_to2_(i, 0).valid == 0) {
malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[block1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[block2], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
- if ((heapinfo1->type == -1) && (heapinfo2->type == -1)) { /* Free block */
+ if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO)
+ && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) {
+ /* Free block */
if (match_pairs) {
match_equals(state, previous);
xbt_dynar_free(&previous);
}
return 0;
- } else if ((heapinfo1->type == 0) && (heapinfo2->type == 0)) { /* Complete block */
+ } else if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED
+ && heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) {
+ /* Complete block */
// TODO, lookup variable type from block type as done for fragmented blocks
|| (block > state->heapsize1) || (block < 1))
return -1;
- if (heapinfo[block].type == -1) { /* Free block */
+ if (heapinfo[block].type == MMALLOC_TYPE_FREE || heapinfo[block].type == MMALLOC_TYPE_HEAPINFO) { /* Free block */
return -1;
- } else if (heapinfo[block].type == 0) { /* Complete block */
+ } else if (heapinfo[block].type == MMALLOC_TYPE_UNFRAGMENTED) { /* Complete block */
return (int) heapinfo[block].busy_block.busy_size;
} else {
frag =
} else {
- if (state->heapinfo1[i].type == -1) { /* Free block */
+ if (state->heapinfo1[i].type == MMALLOC_TYPE_FREE
+ || state->heapinfo1[i].type == MMALLOC_TYPE_HAPINFO) { /* Free block */
i++;
continue;
}
- if (state->heapinfo1[i].type == 0) { /* Large block */
+ if (state->heapinfo1[i].type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */
if (state->heapinfo1[i].busy_block.size !=
state->heapinfo2[i].busy_block.size) {
type = mdp->heapinfo[block].type;
switch (type) {
- case -1: /* Already free */
+ case MMALLOC_TYPE_HEAPINFO:
UNLOCK(mdp);
- THROWF(system_error, 0, "Asked to free a fragment in a block that is already free. I'm puzzled\n");
+ THROWF(system_error, 0, "Asked to free a fragment in a heapinfo block. I'm confused.\n");
+ break;
+
+ case MMALLOC_TYPE_FREE: /* Already free */
+ UNLOCK(mdp);
+ THROWF(system_error, 0, "Asked to free a fragment in a block that is already free. I'm puzzled.\n");
break;
- case 0:
+ case MMALLOC_TYPE_UNFRAGMENTED:
/* Get as many statistics as early as we can. */
mdp -> heapstats.chunks_used--;
mdp -> heapstats.bytes_used -=
mdp->heapinfo[i].free_block.size += mdp->heapinfo[block].busy_block.size;
/* Mark all my ex-blocks as free */
for (it=0; it<mdp->heapinfo[block].busy_block.size; it++) {
- if (mdp->heapinfo[block+it].type <0) {
+ if (mdp->heapinfo[block+it].type < 0) {
fprintf(stderr,"Internal Error: Asked to free a block already marked as free (block=%lu it=%d type=%lu). Please report this bug.\n",
(unsigned long)block,it,(unsigned long)mdp->heapinfo[block].type);
abort();
}
- mdp->heapinfo[block+it].type = -1;
+ mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE;
}
block = i;
(unsigned long)block,it,(unsigned long)mdp->heapinfo[block].free_block.size,(unsigned long)mdp->heapinfo[block].type);
abort();
}
- mdp->heapinfo[block+it].type = -1;
+ mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE;
}
}
break;
default:
+ if (type < 0) {
+ fprintf(stderr, "Unkown mmalloc block type.\n");
+ abort();
+ }
+
/* Do some of the statistics. */
mdp -> heapstats.chunks_used--;
mdp -> heapstats.bytes_used -= 1 << type;
xbt_swag_remove(&mdp->heapinfo[block],&mdp->fraghead[type]);
/* pretend that this block is used and free it so that it gets properly coalesced with adjacent free blocks */
- mdp->heapinfo[block].type = 0;
+ mdp->heapinfo[block].type = MMALLOC_TYPE_UNFRAGMENTED;
mdp->heapinfo[block].busy_block.size = 1;
mdp->heapinfo[block].busy_block.busy_size = 0;
int bytes = 0;
while(i<=((struct mdesc *)heap)->heaplimit){
- if(((struct mdesc *)heap)->heapinfo[i].type == 0){
+ if(((struct mdesc *)heap)->heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){
if(((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size > 0)
bytes += ((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size;
- }else if(((struct mdesc *)heap)->heapinfo[i].type > 0){
+ } else if(((struct mdesc *)heap)->heapinfo[i].type > 0){
for(j=0; j < (size_t) (BLOCKSIZE >> ((struct mdesc *)heap)->heapinfo[i].type); j++){
if(((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j] > 0)
bytes += ((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j];
ssize_t mmalloc_get_busy_size(xbt_mheap_t heap, void *ptr){
ssize_t block = ((char*)ptr - (char*)(heap->heapbase)) / BLOCKSIZE + 1;
- if(heap->heapinfo[block].type == -1)
+ if(heap->heapinfo[block].type < 0)
return -1;
- else if(heap->heapinfo[block].type == 0)
+ else if(heap->heapinfo[block].type == MMALLOC_TYPE_UNFRAGMENTED)
return heap->heapinfo[block].busy_block.busy_size;
else{
ssize_t frag = ((uintptr_t) (ADDR2UINT (ptr) % (BLOCKSIZE))) >> heap->heapinfo[block].type;
return (result);
}
+/** Initialise heapinfo about the heapinfo pages :)
+ *
+ */
+static void initialize_heapinfo_heapinfo(xbt_mheap_t mdp)
+{
+ // Update heapinfo about the heapinfo pages (!):
+ xbt_assert((uintptr_t) mdp->heapinfo % BLOCKSIZE == 0);
+ int block = BLOCK(mdp->heapinfo);
+ size_t nblocks = mdp->heapsize * sizeof(malloc_info) / BLOCKSIZE;
+ // Mark them as free:
+ for (size_t j=0; j!=nblocks; ++j) {
+ mdp->heapinfo[block+j].type = MMALLOC_TYPE_FREE;
+ mdp->heapinfo[block+j].free_block.size = 0;
+ mdp->heapinfo[block+j].free_block.next = 0;
+ mdp->heapinfo[block+j].free_block.prev = 0;
+ }
+ mdp->heapinfo[block].free_block.size = nblocks;
+}
+
/* Finish the initialization of the mheap. If we want to inline it
* properly, we need to make the align function publicly visible, too */
static void initialize(xbt_mheap_t mdp)
int i;
malloc_info mi; /* to compute the offset of the swag hook */
+ // Update mdp meta-data:
mdp->heapsize = HEAP / BLOCKSIZE;
mdp->heapinfo = (malloc_info *)
align(mdp, mdp->heapsize * sizeof(malloc_info));
+ mdp->heapbase = (void *) mdp->heapinfo;
+ mdp->flags |= MMALLOC_INITIALIZED;
+ // Update root heapinfo:
memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info));
- mdp->heapinfo[0].type=-1;
+ mdp->heapinfo[0].type = MMALLOC_TYPE_FREE;
mdp->heapinfo[0].free_block.size = 0;
mdp->heapinfo[0].free_block.next = mdp->heapinfo[0].free_block.prev = 0;
mdp->heapindex = 0;
- mdp->heapbase = (void *) mdp->heapinfo;
- mdp->flags |= MMALLOC_INITIALIZED;
+
+ initialize_heapinfo_heapinfo(mdp);
for (i=0;i<BLOCKLOG;i++) {
xbt_swag_init(&(mdp->fraghead[i]),
/* mark the space previously occupied by the block info as free by first marking it
* as occupied in the regular way, and then freing it */
for (it=0; it<BLOCKIFY(mdp->heapsize * sizeof(malloc_info)); it++){
- newinfo[BLOCK(oldinfo)+it].type = 0;
+ newinfo[BLOCK(oldinfo)+it].type = MMALLOC_TYPE_UNFRAGMENTED;
newinfo[BLOCK(oldinfo)+it].busy_block.ignore = 0;
}
newinfo[BLOCK(oldinfo)].busy_block.busy_size = size;
mfree(mdp, (void *) oldinfo);
mdp->heapsize = newsize;
+
+ initialize_heapinfo_heapinfo(mdp);
}
mdp->heaplimit = BLOCK((char *) result + size);
block = BLOCK(result);
for (it=0;it<blocks;it++){
- mdp->heapinfo[block+it].type = 0;
+ mdp->heapinfo[block+it].type = MMALLOC_TYPE_UNFRAGMENTED;
mdp->heapinfo[block+it].busy_block.busy_size = 0;
mdp->heapinfo[block+it].busy_block.ignore = 0;
+ mdp->heapinfo[block+it].busy_block.size = 0;
}
mdp->heapinfo[block].busy_block.size = blocks;
mdp->heapinfo[block].busy_block.busy_size = requested_size;
}
for (it=0;it<blocks;it++){
- mdp->heapinfo[block+it].type = 0;
+ mdp->heapinfo[block+it].type = MMALLOC_TYPE_UNFRAGMENTED;
mdp->heapinfo[block+it].busy_block.busy_size = 0;
mdp->heapinfo[block+it].busy_block.ignore = 0;
}
int fragment2;
}s_heap_area_pair_t, *heap_area_pair_t;
+#define MMALLOC_TYPE_HEAPINFO (-2)
+#define MMALLOC_TYPE_FREE (-1)
+#define MMALLOC_TYPE_UNFRAGMENTED 0
+/* >0 values are fragmented blocks */
+
/* Data structure giving per-block information.
*
* There is one such structure in the mdp->heapinfo array per block used in that heap,
type = mdp->heapinfo[block].type;
switch (type) {
- case -1:
+ case MMALLOC_TYPE_HEAPINFO:
+ fprintf(stderr, "Asked realloc a fragment coming from a heapinfo block. I'm confused.\n");
+ abort();
+ break;
+
+ case MMALLOC_TYPE_FREE:
fprintf(stderr, "Asked realloc a fragment coming from a *free* block. I'm puzzled.\n");
abort();
break;
- case 0:
+ case MMALLOC_TYPE_UNFRAGMENTED:
/* Maybe reallocate a large block to a small fragment. */
if (size <= BLOCKSIZE / 2) { // Full block -> Fragment; no need to optimize for time
/* The new size is smaller; return excess memory to the free list. */
//printf("(%s) return excess memory...",xbt_thread_self_name());
for (it= block+blocks; it< mdp->heapinfo[block].busy_block.size ; it++){
- mdp->heapinfo[it].type = 0; // FIXME that should be useless, type should already be 0 here
+ mdp->heapinfo[it].type = MMALLOC_TYPE_UNFRAGMENTED; // FIXME that should be useless, type should already be 0 here
mdp->heapinfo[it].busy_block.ignore = 0;
}
default: /* Fragment -> ??; type=logarithm to base two of the fragment size. */
+ if (type < 0) {
+ fprintf(stderr, "Unkown mmalloc block type.\n");
+ abort();
+ }
+
if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) {
/* The new size is the same kind of fragment. */
//printf("(%s) new size is same kind of fragment...",xbt_thread_self_name());