FreeBSD/sys/kern/subr_unit.c
/*
 * Free a unr.
 *
 * If we can save unrs by using a bitmap, do so.
 */
Free a unr.
If we can save unrs by using a bitmap, do so.
Free a unr . If we can save unrs by using a bitmap do so .
static void
free_unrl(struct unrhdr *uh, u_int item, void **p1, void **p2)
{
	struct unr *up, *upp, *upn;
	struct unrb *ub;
	u_int pl;
	KASSERT(item >= uh->low && item <= uh->high,
	    ("UNR: free_unr(%u) out of range [%u...%u]",
	     item, uh->low, uh->high));
	check_unrhdr(uh, __LINE__);
	item -= uh->low;
	upp = TAILQ_FIRST(&uh->head);
	if (item + 1 == uh->first && upp == NULL) {
		uh->last++;
		uh->first--;
		uh->busy--;
		check_unrhdr(uh, __LINE__);
		return;
	}
	if (item < uh->first) {
		up = new_unr(uh, p1, p2);
		up->ptr = uh;
		up->len = uh->first - item;
		TAILQ_INSERT_HEAD(&uh->head, up, list);
		uh->first -= up->len;
	}
	item -= uh->first;
	TAILQ_FOREACH(up, &uh->head, list) {
		if (up->len > item)
			break;
		item -= up->len;
	}
	if (is_bitmap(uh, up)) {
		ub = up->ptr;
		KASSERT(bit_test(ub->map, item) != 0,
		    ("UNR: Freeing free item %d (bitmap)\n", item));
		bit_clear(ub->map, item);
		uh->busy--;
		collapse_unr(uh, up);
		return;
	}
	KASSERT(up->ptr == uh, ("UNR Freeing free item %d (run))\n", item));
	if (up->len == 1) {
		up->ptr = NULL;
		uh->busy--;
		collapse_unr(uh, up);
		return;
	}
	upp = TAILQ_PREV(up, unrhd, list);
	if (item == 0 && upp != NULL && upp->ptr == NULL) {
		upp->len++;
		up->len--;
		uh->busy--;
		collapse_unr(uh, up);
		return;
	}
	upn = TAILQ_NEXT(up, list);
	if (item == up->len - 1 && upn != NULL && upn->ptr == NULL) {
		upn->len++;
		up->len--;
		uh->busy--;
		collapse_unr(uh, up);
		return;
	}
	pl = up->len - (1 + item);
	if (pl > 0) {
		upp = new_unr(uh, p1, p2);
		upp->ptr = uh;
		upp->len = pl;
		TAILQ_INSERT_AFTER(&uh->head, up, upp, list);
	}
	if (item > 0) {
		upp = new_unr(uh, p1, p2);
		upp->len = item;
		upp->ptr = uh;
		TAILQ_INSERT_BEFORE(up, upp, list);
	}
	up->len = 1;
	up->ptr = NULL;
	uh->busy--;
	collapse_unr(uh, up);
}
static void free_unrl ( struct unrhdr * uh , u_int item , void * * p1 , void * * p2 ) { struct unr * up , * upp , * upn ; struct unrb * ub ; u_int pl ; KASSERT ( item >= uh -> low && item <= uh -> high , ( " " , item , uh -> low , uh -> high ) ) ; check_unrhdr ( uh , __LINE__ ) ; item -= uh -> low ; upp = TAILQ_FIRST ( & uh -> head ) ; if ( item + 1 == uh -> first && upp == NULL ) { uh -> last ++ ; uh -> first -- ; uh -> busy -- ; check_unrhdr ( uh , __LINE__ ) ; return ; } if ( item < uh -> first ) { up = new_unr ( uh , p1 , p2 ) ; up -> ptr = uh ; up -> len = uh -> first - item ; TAILQ_INSERT_HEAD ( & uh -> head , up , list ) ; uh -> first -= up -> len ; } item -= uh -> first ; TAILQ_FOREACH ( up , & uh -> head , list ) { if ( up -> len > item ) break ; item -= up -> len ; } if ( is_bitmap ( uh , up ) ) { ub = up -> ptr ; KASSERT ( bit_test ( ub -> map , item ) != 0 , ( " \n " , item ) ) ; bit_clear ( ub -> map , item ) ; uh -> busy -- ; collapse_unr ( uh , up ) ; return ; } KASSERT ( up -> ptr == uh , ( " \n " , item ) ) ; if ( up -> len == 1 ) { up -> ptr = NULL ; uh -> busy -- ; collapse_unr ( uh , up ) ; return ; } upp = TAILQ_PREV ( up , unrhd , list ) ; if ( item == 0 && upp != NULL && upp -> ptr == NULL ) { upp -> len ++ ; up -> len -- ; uh -> busy -- ; collapse_unr ( uh , up ) ; return ; } upn = TAILQ_NEXT ( up , list ) ; if ( item == up -> len - 1 && upn != NULL && upn -> ptr == NULL ) { upn -> len ++ ; up -> len -- ; uh -> busy -- ; collapse_unr ( uh , up ) ; return ; } pl = up -> len - ( 1 + item ) ; if ( pl > 0 ) { upp = new_unr ( uh , p1 , p2 ) ; upp -> ptr = uh ; upp -> len = pl ; TAILQ_INSERT_AFTER ( & uh -> head , up , upp , list ) ; } if ( item > 0 ) { upp = new_unr ( uh , p1 , p2 ) ; upp -> len = item ; upp -> ptr = uh ; TAILQ_INSERT_BEFORE ( up , upp , list ) ; } up -> len = 1 ; up -> ptr = NULL ; uh -> busy -- ; collapse_unr ( uh , up ) ; }
Free a unr.
Free a unr .
/*
	 * Freeing in the ideal split case
	 */ /*
 	 * Freeing in the ->first section.  Create a run starting at the
	 * freed item.  The code below will subdivide it.
	 */ /* Find the item which contains the unit we want to free */ /* Handle bitmap items */ /* Just this one left, reap it */ /* Check if we can shift the item into the previous 'free' run */ /* Check if we can shift the item to the next 'free' run */ /* Split off the tail end, if any. */ /* Split off head end, if any */