FreeBSD/sys/kern/subr_unit.c
/*
 * See if a given unr should be collapsed with a neighbor.
 *
 * NB: called from alloc_unr(), no new memory allocation allowed.
 */
See if a given unr should be collapsed with a neighbor.
NB: called from alloc_unr(), no new memory allocation allowed.
See if a given unr should be collapsed with a neighbor . NB : called from alloc_unr () no new memory allocation allowed .
static void
collapse_unr(struct unrhdr *uh, struct unr *up)
{
	struct unr *upp;
	struct unrb *ub;
	if (is_bitmap(uh, up)) {
		ub = up->ptr;
		if (ub_full(ub, up->len)) {
			delete_unr(uh, up->ptr);
			up->ptr = uh;
		} else if (ub_empty(ub, up->len)) {
			delete_unr(uh, up->ptr);
			up->ptr = NULL;
		}
	}
	if (up->len == 0) {
		upp = TAILQ_PREV(up, unrhd, list);
		if (upp == NULL)
			upp = TAILQ_NEXT(up, list);
		TAILQ_REMOVE(&uh->head, up, list);
		delete_unr(uh, up);
		up = upp;
	}
	if (up != NULL) {
		upp = TAILQ_PREV(up, unrhd, list);
		if (upp != NULL && up->ptr == upp->ptr) {
			up->len += upp->len;
			TAILQ_REMOVE(&uh->head, upp, list);
			delete_unr(uh, upp);
			}
		upp = TAILQ_NEXT(up, list);
		if (upp != NULL && up->ptr == upp->ptr) {
			up->len += upp->len;
			TAILQ_REMOVE(&uh->head, upp, list);
			delete_unr(uh, upp);
		}
	}
	upp = TAILQ_FIRST(&uh->head);
	if (upp != NULL && upp->ptr == uh) {
		uh->first += upp->len;
		TAILQ_REMOVE(&uh->head, upp, list);
		delete_unr(uh, upp);
		if (up == upp)
			up = NULL;
	}
	upp = TAILQ_LAST(&uh->head, unrhd);
	if (upp != NULL && upp->ptr == NULL) {
		uh->last += upp->len;
		TAILQ_REMOVE(&uh->head, upp, list);
		delete_unr(uh, upp);
		if (up == upp)
			up = NULL;
	}
	while (optimize_unr(uh))
		continue;
}
static void collapse_unr ( struct unrhdr * uh , struct unr * up ) { struct unr * upp ; struct unrb * ub ; if ( is_bitmap ( uh , up ) ) { ub = up -> ptr ; if ( ub_full ( ub , up -> len ) ) { delete_unr ( uh , up -> ptr ) ; up -> ptr = uh ; } else if ( ub_empty ( ub , up -> len ) ) { delete_unr ( uh , up -> ptr ) ; up -> ptr = NULL ; } } if ( up -> len == 0 ) { upp = TAILQ_PREV ( up , unrhd , list ) ; if ( upp == NULL ) upp = TAILQ_NEXT ( up , list ) ; TAILQ_REMOVE ( & uh -> head , up , list ) ; delete_unr ( uh , up ) ; up = upp ; } if ( up != NULL ) { upp = TAILQ_PREV ( up , unrhd , list ) ; if ( upp != NULL && up -> ptr == upp -> ptr ) { up -> len += upp -> len ; TAILQ_REMOVE ( & uh -> head , upp , list ) ; delete_unr ( uh , upp ) ; } upp = TAILQ_NEXT ( up , list ) ; if ( upp != NULL && up -> ptr == upp -> ptr ) { up -> len += upp -> len ; TAILQ_REMOVE ( & uh -> head , upp , list ) ; delete_unr ( uh , upp ) ; } } upp = TAILQ_FIRST ( & uh -> head ) ; if ( upp != NULL && upp -> ptr == uh ) { uh -> first += upp -> len ; TAILQ_REMOVE ( & uh -> head , upp , list ) ; delete_unr ( uh , upp ) ; if ( up == upp ) up = NULL ; } upp = TAILQ_LAST ( & uh -> head , unrhd ) ; if ( upp != NULL && upp -> ptr == NULL ) { uh -> last += upp -> len ; TAILQ_REMOVE ( & uh -> head , upp , list ) ; delete_unr ( uh , upp ) ; if ( up == upp ) up = NULL ; } while ( optimize_unr ( uh ) ) continue ; }
See if a given unr should be collapsed with a neighbor.
See if a given unr should be collapsed with a neighbor .
/* If bitmap is all set or clear, change it to runlength */ /* If nothing left in runlength, delete it */ /* If we have "hot-spot" still, merge with neighbor if possible */ /* Merge into ->first if possible */ /* Merge into ->last if possible */ /* Try to make bitmaps */