Example #1
0
// k_heap_compress - Merge free blocks
// This function "compresses" the linked list, consolidating as many adjacent free blocks as possible, to reduce fragmentation.
int k_heap_compress() {
    k_heap_blk* blk = heap.start;
    k_heap_blk* next = NULL;
    int blks_deleted = 0;
    
    __dynmem_lock.lock_cli();
    while((blk != NULL) && (blk->next != NULL)) { // Don't compress the first or last block in the heap.
        next = blk->next;
        if(blk->prev != NULL) {
            if(!blk->used && !blk->prev->used) { // If both the current block and the one before it are free...
                // ...then _delete_ this block. 
                k_heap_delete(blk);
                blks_deleted++;
            }
        }
        blk = next;
    }
    
    if((heap.end->prev != NULL) && (!heap.end->prev->used)) {
        k_heap_delete(heap.end);
        blks_deleted++;
    }
    __dynmem_lock.unlock_cli();
    return blks_deleted;
}
Example #2
0
// k_heap_add_at_offset - Add a new heap block
// This function places a new heap block in memory, linked to an "origin" block.
void k_heap_add_at_offset(k_heap_blk* origin_blk, int block_offset) {
    __dynmem_lock.lock_cli();
    k_heap_blk* blk = (k_heap_blk*)((size_t)origin_blk+(block_offset*HEAP_BLK_SIZE));
    blk->prev = origin_blk;
    blk->next = origin_blk->next;
    blk->magic = HEAP_MAGIC_NUMBER;
    
    blk->prev->next = blk;
    if(blk->next != NULL)
        blk->next->prev = blk;
    else
        heap.end = blk;
    __dynmem_lock.unlock_cli();
}
Example #3
0
// k_heap_delete - Unlink a block
// This function removes a block from the linked list, effectively "deleting" it.
void k_heap_delete(k_heap_blk* blk) {
    __dynmem_lock.lock_cli();
    if(blk == NULL) {
        panic("dynmem: Attempted to delete NULL block!");
    }
    if(blk->prev != NULL) {
        blk->prev->next = blk->next;
    } else {
        return; // can't delete the first block
    }
    if(blk->next != NULL) {
        blk->next->prev = blk->prev;
    } else {
        heap.end = blk->prev;
    }
    blk->next = NULL;
    blk->prev = NULL;
    blk->magic = 0;
    blk->used = false;
    __dynmem_lock.unlock_cli();
}