FreeBSD/sys/kern/subr_blist.c
/*
 * blist_meta_alloc() -	allocate at a meta in the radix tree.
 *
 *	Attempt to allocate at a meta node.  If we can't, we update
 *	bighint and return a failure.  Updating bighint optimize future
 *	calls that hit this node.  We have to check for our collapse cases
 *	and we have a few optimizations strewn in as well.
 */
allocate at a meta in the radix tree.
Attempt to allocate at a meta node.  If we can't, we update
bighint and return a failure.  Updating bighint optimize future
calls that hit this node.  We have to check for our collapse cases
and we have a few optimizations strewn in as well.
allocate at a meta in the radix tree . Attempt to allocate at a meta node . If we can ' t we update bighint and return a failure . Updating bighint optimize future calls that hit this node . We have to check for our collapse cases and we have a few optimizations strewn in as well .
static daddr_t
blst_meta_alloc(
	blmeta_t *scan, 
	daddr_t blk,
	daddr_t count,
	daddr_t radix, 
	int skip
) {
	int i;
	int next_skip = ((u_int)skip / BLIST_META_RADIX);
	if (scan->u.bmu_avail == 0)  {
		scan->bm_bighint = count;
		return(SWAPBLK_NONE);
	}
	if (scan->u.bmu_avail == radix) {
		radix /= BLIST_META_RADIX;
		for (i = 1; i <= skip; i += next_skip) {
			if (scan[i].bm_bighint == (daddr_t)-1)
				break;
			if (next_skip == 1) {
				scan[i].u.bmu_bitmap = (u_daddr_t)-1;
				scan[i].bm_bighint = BLIST_BMAP_RADIX;
			} else {
				scan[i].bm_bighint = radix;
				scan[i].u.bmu_avail = radix;
			}
		}
	} else {
		radix /= BLIST_META_RADIX;
	}
	for (i = 1; i <= skip; i += next_skip) {
		if (count <= scan[i].bm_bighint) {
			daddr_t r;
			if (next_skip == 1) {
				r = blst_leaf_alloc(&scan[i], blk, count);
			} else {
				r = blst_meta_alloc(&scan[i], blk, count, radix, next_skip - 1);
			}
			if (r != SWAPBLK_NONE) {
				scan->u.bmu_avail -= count;
				if (scan->bm_bighint > scan->u.bmu_avail)
					scan->bm_bighint = scan->u.bmu_avail;
				return(r);
			}
		} else if (scan[i].bm_bighint == (daddr_t)-1) {
			break;
		} else if (count > radix) {
			panic("blist_meta_alloc: allocation too large");
		}
		blk += radix;
	}
	if (scan->bm_bighint >= count)
		scan->bm_bighint = count - 1;
	return(SWAPBLK_NONE);
}
static daddr_t blst_meta_alloc ( blmeta_t * scan , daddr_t blk , daddr_t count , daddr_t radix , int skip ) { int i ; int next_skip = ( ( u_int ) skip / BLIST_META_RADIX ) ; if ( scan -> u . bmu_avail == 0 ) { scan -> bm_bighint = count ; return ( SWAPBLK_NONE ) ; } if ( scan -> u . bmu_avail == radix ) { radix /= BLIST_META_RADIX ; for ( i = 1 ; i <= skip ; i += next_skip ) { if ( scan [ i ] . bm_bighint == ( daddr_t ) - 1 ) break ; if ( next_skip == 1 ) { scan [ i ] . u . bmu_bitmap = ( u_daddr_t ) - 1 ; scan [ i ] . bm_bighint = BLIST_BMAP_RADIX ; } else { scan [ i ] . bm_bighint = radix ; scan [ i ] . u . bmu_avail = radix ; } } } else { radix /= BLIST_META_RADIX ; } for ( i = 1 ; i <= skip ; i += next_skip ) { if ( count <= scan [ i ] . bm_bighint ) { daddr_t r ; if ( next_skip == 1 ) { r = blst_leaf_alloc ( & scan [ i ] , blk , count ) ; } else { r = blst_meta_alloc ( & scan [ i ] , blk , count , radix , next_skip - 1 ) ; } if ( r != SWAPBLK_NONE ) { scan -> u . bmu_avail -= count ; if ( scan -> bm_bighint > scan -> u . bmu_avail ) scan -> bm_bighint = scan -> u . bmu_avail ; return ( r ) ; } } else if ( scan [ i ] . bm_bighint == ( daddr_t ) - 1 ) { break ; } else if ( count > radix ) { panic ( " " ) ; } blk += radix ; } if ( scan -> bm_bighint >= count ) scan -> bm_bighint = count - 1 ; return ( SWAPBLK_NONE ) ; }
blist_meta_alloc() - allocate at a meta in the radix tree.
blist_meta_alloc () - allocate at a meta in the radix tree .
/*
		 * ALL-ALLOCATED special case
		 */ /*
		 * ALL-FREE special case, initialize uninitialize
		 * sublevel.
		 */ /*
			 * count fits in object
			 */ /*
			 * Terminator
			 */ /*
			 * count does not fit in object even if it were
			 * complete free.
			 */ /*
	 * We couldn't allocate count in this subtree, update bighint.
	 */