Beispiel #1
0
/*
 * 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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
/*
 * 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();
}