func()

in freelist.go [175:220]


func (f *freelist) AllocRegionsWith(order *allocOrder, n uint, fn func(region)) {
	if n == 0 {
		return
	}

	var (
		last int // last region to allocate from
		L    = len(f.regions)
		N    = n // number of pages to be allocated from 'last' region
	)

	if N > f.avail {
		// not enough space -> return early
		return
	}

	// Collect indices of regions to be allocated from.
	for i, end, next := order.iter(L); i != end; i = next(i) {
		count := uint(f.regions[i].count)
		if count >= N {
			last = i
			break
		}
		N -= count
	}

	// Compute region split on last region to be allocated from.
	selected := f.regions[last]
	allocated, leftover := order.allocFromRegion(selected, uint32(N))

	invariant.Check(allocated.count == uint32(N), "allocation mismatch")
	invariant.Check(allocated.count+leftover.count == selected.count, "region split page count mismatch")

	// Implicitely update last allocated region to match the allocation size
	// and report all regions allocated.
	f.regions[last] = allocated
	for i, end := order.reportRange(last, L); i != end; i++ {
		fn(f.regions[i])
	}

	// update free regions
	f.regions[last] = leftover
	start, end := order.keepRange(last, L, leftover.count != 0)
	f.regions = f.regions[start:end]
	f.avail -= n
}