/* * Logika alokacije ista je kao i kod prvog odgovarajućeg. * Dodjeljuje se blok zahtjevane veličine. * Pretraživanje započinje od početka liste. * * VAŽNO: * Glavna razlika u odnosu na prvog odgovarajućeg je što je lista SORTIRANA (uzlazno!). * */ void *bf_alloc ( bf_mpool_t *mpool, size_t size ) { bf_hdr_t *iter, *chunk; ASSERT ( mpool ); size += sizeof (size_t) * 2; /* add header and tail size */ if ( size < HEADER_SIZE ) size = HEADER_SIZE; /* align request size to higher 'size_t' boundary */ ALIGN_FW ( size ); //TRAŽENJE SLOBODNOG BLOKA //PRETRAGA ZAPOČINJE OD PRVOG SLOBODNOG BLOKA iter = mpool->first; //dok postoje slobodni blokovi i dok je veličina manja od potrebne veličine, traži while ( iter != NULL && iter->size < size ) iter = iter->next; //ako nisam našao blok dovoljne veličine, vrati null if ( iter == NULL ) return NULL; /* no adequate free chunk found */ //inače, ako je veličina pronađenog slobodnog bloka if ( iter->size >= size + HEADER_SIZE ) { /* split chunk */ /* first part remains in free list, just update size */ iter->size -= size; CLONE_SIZE_TO_TAIL ( iter ); chunk = GET_AFTER ( iter ); chunk->size = size; } else { /* give whole chunk */ chunk = iter; /* remove it from free list */ bf_remove_chunk ( mpool, chunk ); } //označi kao zauzetog MARK_USED ( chunk ); CLONE_SIZE_TO_TAIL ( chunk ); //vrati blok return ( (void *) chunk ) + sizeof (size_t); }
/*! * Get free chunk with required size (or slightly bigger) * \param mpool Memory pool to be used (if NULL default pool is used) * \param size Requested chunk size * \return Block address, NULL if can't find adequate free chunk */ void *ffs_alloc ( ffs_mpool_t *mpool, size_t size ) { ffs_hdr_t *iter, *chunk; ASSERT ( mpool ); size += sizeof (size_t) * 2; /* add header and tail size */ if ( size < HEADER_SIZE ) size = HEADER_SIZE; /* align request size to higher 'size_t' boundary */ ALIGN_FW ( size ); iter = mpool->first; while ( iter != NULL && iter->size < size ) iter = iter->next; if ( iter == NULL ) return NULL; /* no adequate free chunk found */ if ( iter->size >= size + HEADER_SIZE ) { /* split chunk */ /* first part remains in free list, just update size */ iter->size -= size; CLONE_SIZE_TO_TAIL ( iter ); chunk = GET_AFTER ( iter ); chunk->size = size; } else { /* give whole chunk */ chunk = iter; /* remove it from free list */ ffs_remove_chunk ( mpool, chunk ); } MARK_USED ( chunk ); CLONE_SIZE_TO_TAIL ( chunk ); return ( (void *) chunk ) + sizeof (size_t); }
/* 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; }