/* * coalesce - boundary tag coalescing * will delete coalesced old blocks from the free list, and * will insert the new block to the free list * return pointer to coalesced block */ static void *coalesce(void *bp) { size_t prev_alloc, next_alloc; size_t size; prev_alloc = block_prev_alloc(bp); next_alloc = block_alloc(next_block(bp)); size = block_size(bp); dbg_printf("want to coalesce %d size block, prev alloc: %d, next alloc: %d\n", (int)size, (int)prev_alloc, (int)next_alloc); if (prev_alloc && next_alloc) { // alloc - free - alloc return bp; } else if (prev_alloc && !next_alloc) { // alloc - free - free delete_from_list(bp); delete_from_list(next_block(bp)); if (next_block(bp) == last_block) { last_block = bp; } size += block_size(next_block(bp)); mark(bp, size, prev_alloc, 0); insert_to_list(bp); } else if (!prev_alloc && next_alloc) { // free - free (- alloc) delete_from_list(prev_block(bp)); delete_from_list(bp); if (bp == last_block) { last_block = prev_block(bp); } size += block_size(prev_block(bp)); bp = prev_block(bp); mark(bp, size, block_prev_alloc(bp), 0); insert_to_list(bp); } else if (!prev_alloc && !next_alloc) { // free - free - free delete_from_list(prev_block(bp)); delete_from_list(bp); delete_from_list(next_block(bp)); if (next_block(bp) == last_block) { last_block = prev_block(bp); } size += block_size(prev_block(bp)) + block_size(next_block(bp)); bp = prev_block(bp); mark(bp, size, block_prev_alloc(bp), 0); insert_to_list(bp); } return bp; }
void xfree(char * p, int size) { char * q; /* At this point we could check that the in_use bit for this block is set, and also check that the size is right */ clear_use(p); /* mark this block as unused */ if (p == last_block) { while (1) { q = prev_block(p); if (q == p) { last_block = NULL; end_of_array = p; break; /* only happens when we get to the beginning */ } if (in_use(q)) { last_block = q; end_of_array = p; break; } p = q; } } space_in_use -= size; }
void storage_get_block(struct plugin_instance *p, int64_t off, float64_t *cells, size_t len) { int i, j; ssize_t ret; struct stat sb; struct timedb_hdr *th; uint8_t *binary; uint64_t last; ret = fstat(p->timedb_fd, &sb); if (ret < 0) { printd("Cannot fstat the database!\n"); return; } binary = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, p->timedb_fd, 0); if (binary == MAP_FAILED) { printd("Error mmaping db: %s\n", strerror(errno)); return; } th = (struct timedb_hdr *) binary; last = th->offset_next; for (i = 0; i < th->block_entries; ++i) { //FIXME: do it more efficient last = prev_block(th, binary, sb.st_size, last); if (i == off) { for (j = 0; j < len; ++j) cells[j] = block_to_data_off(binary +last, j); break; } } munmap(binary, sb.st_size); }
/* * mm_checkheap */ void mm_checkheap(int verbose){ void *bp; unsigned *list_p; unsigned *pred, *succ; int i; if (!verbose) { return; } bp = data_head + DSIZE; /* checking the heap */ /* prologue */ if (!(block_size(bp) == 8 && block_alloc(bp) == 1)) { printf("Invariant Error: prologue block\n"); } /* blocks */ bp = next_block(bp); while (block_size(bp) != 0) { if ((long)bp % DSIZE != 0) { printf("Invariant Error: block's address isn't aligned\n"); } if (!block_alloc(bp)) { if (*(int *)HEAD(bp) != *(int *)FOOT(bp)) { printf("Invariant Error: block head and foot don't match\n"); } } if (!block_prev_alloc(bp)) { if (block_prev_alloc(bp) != block_alloc(prev_block(bp))) { printf("Invariant Error: prev alloc bit doesn't match prev block\n"); } if (block_alloc(bp) == 0) { printf("Inveriant Error: find consecutive free blocks\n"); } } if (block_alloc(bp) == 0 && block_alloc(next_block(bp)) == 0) { printf("Inveriant Error: find consecutive free blocks\n"); } if (block_size(bp) < 4 * WSIZE) { printf("Invariant Error: block is too small\n"); } bp = next_block(bp); } /* epilogue */ if (!(block_size(bp) == 0 && block_alloc(bp) == 1)) { printf("Invariant Error: epilogue block\n"); } /* checking the free list */ list_p = (unsigned *)heap_head; for (i = 0; i < ARRAYSIZE; i++) { if (!*list_p) { continue; } bp = (unsigned *)r2a((size_t)*list_p); while (bp != NULL) { pred = pred_block(bp); succ = succ_block(bp); if (pred != NULL) { if (*(pred + 1) != a2r((size_t)bp)) { printf("Invariant Error: inconsistent pointer\n"); } } if (succ != NULL) { if (*succ != a2r((size_t)bp)) { printf("Invariant Error: inconsistent pointer\n"); } } if (get_list(block_size((void *)bp)) != list_p) { printf("Invariant Error: block size doesn't match list\n"); } bp = succ; } list_p++; } print_heap(); }