/*! * Free memory chunk * \param mpool Memory pool to be used (if NULL default pool is used) * \param chunk Chunk location (starting address) * \return 0 if successful, -1 otherwise */ int ffs_free ( ffs_mpool_t *mpool, void *chunk_to_be_freed ) { ffs_hdr_t *chunk, *before, *after; ASSERT ( mpool && chunk_to_be_freed ); chunk = chunk_to_be_freed - sizeof (size_t); MARK_FREE ( chunk ); /* mark it as free */ /* join with left? */ before = ( (void *) chunk ) - sizeof(size_t); if ( CHECK_FREE ( before ) ) { before = GET_HDR ( before ); ffs_remove_chunk ( mpool, before ); before->size += chunk->size; /* join */ chunk = before; } /* join with right? */ after = GET_AFTER ( chunk ); if ( CHECK_FREE ( after ) ) { ffs_remove_chunk ( mpool, after ); chunk->size += after->size; /* join */ } /* insert chunk in free list */ ffs_insert_chunk ( mpool, chunk ); /* set chunk tail */ CLONE_SIZE_TO_TAIL ( chunk ); return 0; }
/* * Nakon oslobađanja bloka radi se sortiranje liste tako da je na početku najmanji blok, * a na kraju najveći blok. * Blok se dodaje listu koja se: * 1. blok spaja sa susjedima ukoliko su slobodni * 2. sortira listu */ int bf_free ( bf_mpool_t *mpool, void *chunk_to_be_freed ) { bf_hdr_t *chunk, *before, *after; ASSERT ( mpool && chunk_to_be_freed ); chunk = chunk_to_be_freed - sizeof (size_t); MARK_FREE ( chunk ); /* mark it as free */ /* join with left? */ before = ( (void *) chunk ) - sizeof(size_t); if ( CHECK_FREE ( before ) ) { before = GET_HDR ( before ); bf_remove_chunk ( mpool, before ); before->size += chunk->size; /* join */ chunk = before; } /* join with right? */ after = GET_AFTER ( chunk ); if ( CHECK_FREE ( after ) ) { bf_remove_chunk ( mpool, after ); chunk->size += after->size; /* join */ } /* insert chunk in free list */ //dodaje slobodan blok u listu i sortira bf_insert_chunk ( mpool, chunk ); /* set chunk tail */ CLONE_SIZE_TO_TAIL ( chunk ); bf_hdr_t *iter; iter = mpool->first; print("Ispis slobodnih blokova:\n"); while( iter != NULL ) { print("%d -> ", iter->size); iter = iter->next; } print("\n"); return 0; }
/* * free */ void free (void *bp) { if(bp == 0) return; if (heap_listp == 0){ mm_init(); } #ifdef DEBUG printf("free: before.\n"); mm_checkheap(1); #endif MARK_FREE(HDRP(bp)); PUT(FTRP(bp), GET(HDRP(bp))); coalesce(bp); #ifdef DEBUG printf("free: after.\n"); mm_checkheap(1); printf("\n\n"); #endif }
/* Inicijalizacija ostaje ista kao kod prvog odgovarajućeg. Iz bloka slobodne memorije, registriramo se na blok veličine size i na njemu ćemo raditi alokaciju. Veličina podsustava za alokaciju određen je u jezgri i inicijalizaciju podsustava radi jezgra! */ void *bf_init ( void *mem_segm, size_t size ) { size_t start, end; bf_hdr_t *chunk, *border; bf_mpool_t *mpool; ASSERT ( mem_segm && size > sizeof (bf_hdr_t) * 2 ); /* align all on 'size_t' (if already not aligned) */ start = (size_t) mem_segm; end = start + size; ALIGN_FW ( start ); mpool = (void *) start; /* place mm descriptor here */ start += sizeof (bf_mpool_t); ALIGN ( end ); mpool->first = NULL; if ( end - start < 2 * HEADER_SIZE ) return NULL; border = (bf_hdr_t *) start; border->size = sizeof (size_t); MARK_USED ( border ); chunk = GET_AFTER ( border ); chunk->size = end - start - 2 * sizeof(size_t); MARK_FREE ( chunk ); CLONE_SIZE_TO_TAIL ( chunk ); border = GET_AFTER ( chunk ); border->size = sizeof (size_t); MARK_USED ( border ); bf_insert_chunk ( mpool, chunk ); /* first and only free chunk */ //vraćamo blok nad kojim ćemo raditi alokacije return mpool; }