__inline void remove_free_block(memmap_free_t* mmap) { memmap_t* mmap_alloc = (memmap_t*)mmap; U8 index = get_free_bucket_index(get_block_size(mmap_alloc)); if (!is_last_in_bucket(mmap)) { if (!is_first_in_bucket(mmap)) { set_next_free(get_prev_free(mmap), get_next_free(mmap)); set_prev_free(get_next_free(mmap), get_prev_free(mmap)); } else { mprgmmap[index] = get_next_free(mmap); set_prev_free(get_next_free(mmap), get_next_free(mmap)); } } else { if (!is_first_in_bucket(mmap)) { set_next_free(get_prev_free(mmap), get_prev_free(mmap)); } else { mprgmmap[index] = NULL; } } // "Isolating" the block set_prev_free(mmap, mmap); set_next_free(mmap, mmap); }
/* void memmap_free_init(memmap_free_t* const mmap, U32 size) Initializes a struct of type `memmap_free` with a given size. */ void memmap_free_init(memmap_free_t* const mmap, U32 size) { // memmap is the first field in memmap_free_t memmap_t* memmap_alloc = (memmap_t*)(mmap); memmap_init(memmap_alloc, size); set_prev_free(mmap, mmap); set_next_free(mmap, mmap); }
/* relase po with size N to AVAIL list */ void dkbtfree(void * x){ assert(x!=NULL); node_t * po=x; node_t * block; block=block_merge_left(get_block_pprv(po), po); block=block_merge_right(block, get_block_pnxt(block));/* return new block */ set_block_free(block); set_prev_free(get_block_pnxt(block)); set_prev_used(block); block_insert(block); /*insert into dll */ }
// Macro is evil, inline function is more reliable. static inline void insert_node(int level, void * bp) { char **flist_head = get_head(level); char **flist_tail = get_tail(level); if (!(*flist_head)) { // empty list *flist_head = bp; *flist_tail = bp; set_prev_free(bp, NULL); set_next_free(bp, NULL); } else { if ((char *)bp < (*flist_head)) { // insert at head set_prev_free(*flist_head, bp); set_next_free(bp, *flist_head); set_prev_free(bp, NULL); *flist_head = bp; } else if ((*flist_tail) < (char *)bp) { // insert to tail set_next_free(*flist_tail, bp); set_prev_free(bp, *flist_tail); set_next_free(bp, NULL); *flist_tail = bp; } else { // find some place in the list char * c = *flist_head; while (c < (char *)bp) { c = next_free(c); } set_next_free(prev_free(c), bp); set_prev_free(bp, prev_free(c)); set_prev_free(c, bp); set_next_free(bp, c); } } }
static inline void delete_node(int level, void * bp) { char **flist_head = get_head(level); char **flist_tail = get_tail(level); if (bp == *flist_head) { *flist_head = next_free(bp); if (*flist_head) { set_prev_free(*flist_head, NULL); } else { *flist_tail = NULL; } } else if (bp == *flist_tail) { *flist_tail = prev_free(bp); if (*flist_tail) { set_next_free(*flist_tail, NULL); } else { *flist_head = NULL; } } else { set_next_free(prev_free(bp), next_free(bp)); set_prev_free(next_free(bp), prev_free(bp)); } }
/* * extend_heap - Extend heap with free block and return its block pointer * * Return: * the new free block pointer */ static void *extend_heap(size_t words) { char *bp; size_t size; /* single-word alignment */ size = (words + 1) * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1) return NULL; int prev_alloc = IS_PREV_ALLOC(HDRP(bp)); /* Initialize free block header/footer and the epilogue header */ PUT(HDRP(bp), PACK3(size, prev_alloc << 1, 0)); /* Free block header */ PUT(FTRP(bp), PACK3(size, prev_alloc << 1, 0)); /* Free block footer */ set_prev_free(bp, NULL); set_next_free(bp, NULL); PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ /* Coalesce if the previous block was free */ heap_tailp = coalesce(bp); return heap_tailp; }