class Pool

Defined at line 53 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

Pool is a container that tracks ranges of physical memory and allocates

available regions of RAM from among them.

One initializes a Pool with a variable number of arrays of memory ranges.

Except among allocated types (see Type documentation), the ranges are

permitted to overlap with one another to an arbitrary degree. In practice,

the main array of ranges would be supplied by a ZBI or synthesized from a

legacy booting protocol, while the others would consist of other auxiliary

reserved areas known to be in use at the time of initialization

(e.g., physboot's load image and the data ZBI itself). Despite arbitrarily

overlapping inputs, Pool gives normalized outputs: iteration yields ranges

that are lexicographically ordered, mutually disjoint, and for which

addr + size does not overflow.

kReserved ranges merely exist for the convenience of bootloaders: they

represent holes to be punched out of kFreeRam ranges during normalization

and do not have intrinsic value in and of themselves. Accordingly, Pool does

not explicitly track them after initialization.

Pool dynamically uses ranges of the free RAM it encodes for bookkeeping

space. On initialization, it will attempt to find initial chunks to cover

space to track the first crop of normalized ranges. With further allocation,

fragmentation will increase and Pool will internally allocate more such

space to manage it. Bookkeeping memory will also avoid the zero(th) page.

Pool is neither copyable nor movable.

Public Members

static const uint64_t kBookkeepingChunkSize
static const uint64_t kDefaultMinAddr
static const uint64_t kDefaultMaxAddr

Public Methods

void Pool ()

Default-construction uses the identity mapping for a

BookkeepingAddressToPointer.

Defined at line 113 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (const Pool & )

Defined at line 115 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (Pool && )

Defined at line 116 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (BookkeepingAddressToPointer bookkeeping_pointer)

Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (BookkeepingAddressToPointer bookkeeping_pointer)

Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (BookkeepingAddressToPointer bookkeeping_pointer)

Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void Pool (BookkeepingAddressToPointer bookkeeping_pointer)

Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void ~Pool ()

Defined at line 121 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

Pool & operator= (const Pool & )

Defined at line 126 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

Pool & operator= (Pool && )

Defined at line 127 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)

Initializes a Pool from a variable number of memory ranges, performing an

internal allocation for its internal bookkeeping among the free RAM

encoded in the provided ranges. `default_min_addr` and `default_max_addr`

prescribe default bounds on the addresses Pool is allowed to allocate; the

placement of the internal bookkeeping must respect these.

The provided ranges cannot feature overlap among different allocated

types, or between an allocated type with one of kReserved or kPeripheral;

otherwise, arbitrary overlap is permitted.

fit::failed is returned if there is insufficient free RAM to use for

Pool's initial bookkeeping.

Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)

Initializes a Pool from a variable number of memory ranges, performing an

internal allocation for its internal bookkeeping among the free RAM

encoded in the provided ranges. `default_min_addr` and `default_max_addr`

prescribe default bounds on the addresses Pool is allowed to allocate; the

placement of the internal bookkeeping must respect these.

The provided ranges cannot feature overlap among different allocated

types, or between an allocated type with one of kReserved or kPeripheral;

otherwise, arbitrary overlap is permitted.

fit::failed is returned if there is insufficient free RAM to use for

Pool's initial bookkeeping.

Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)

Initializes a Pool from a variable number of memory ranges, performing an

internal allocation for its internal bookkeeping among the free RAM

encoded in the provided ranges. `default_min_addr` and `default_max_addr`

prescribe default bounds on the addresses Pool is allowed to allocate; the

placement of the internal bookkeeping must respect these.

The provided ranges cannot feature overlap among different allocated

types, or between an allocated type with one of kReserved or kPeripheral;

otherwise, arbitrary overlap is permitted.

fit::failed is returned if there is insufficient free RAM to use for

Pool's initial bookkeeping.

Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)

Initializes a Pool from a variable number of memory ranges, performing an

internal allocation for its internal bookkeeping among the free RAM

encoded in the provided ranges. `default_min_addr` and `default_max_addr`

prescribe default bounds on the addresses Pool is allowed to allocate; the

placement of the internal bookkeeping must respect these.

The provided ranges cannot feature overlap among different allocated

types, or between an allocated type with one of kReserved or kPeripheral;

otherwise, arbitrary overlap is permitted.

fit::failed is returned if there is insufficient free RAM to use for

Pool's initial bookkeeping.

Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

iterator begin ()

Defined at line 152 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

iterator end ()

Defined at line 153 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

bool empty ()

Defined at line 155 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

const Range & front ()

Defined at line 157 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

const Range & back ()

Defined at line 162 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

size_t size ()

Returns the number of tracked, normalized ranges.

Defined at line 168 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void set_access_callback (AccessCallback access_callback)

Sets an allocation callback (see AccessCallback for more details). This

may be called before Init().

Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void set_access_callback (AccessCallback access_callback)

Sets an allocation callback (see AccessCallback for more details). This

may be called before Init().

Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void set_access_callback (AccessCallback access_callback)

Sets an allocation callback (see AccessCallback for more details). This

may be called before Init().

Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void set_access_callback (AccessCallback access_callback)

Sets an allocation callback (see AccessCallback for more details). This

may be called before Init().

Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)

Attempts to allocate memory out of free RAM of the prescribed type, size,

and alignment. An optional upper address bound may be passed: if

unspecified the default upper bound passed to Init() will be respected.

`type` must be an allocated type. `size` must be positive and the following

must hold:

`min_addr.value_or(default_min_addr)

<

= max_addr.value_or(default_max_addr)`

Any returned address is guaranteed to be nonzero.

fit::failed is returned if there is insufficient free RAM to track any

new ranges or if there is no free RAM that meets the given constraints.

Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)

Attempts to allocate memory out of free RAM of the prescribed type, size,

and alignment. An optional upper address bound may be passed: if

unspecified the default upper bound passed to Init() will be respected.

`type` must be an allocated type. `size` must be positive and the following

must hold:

`min_addr.value_or(default_min_addr)

<

= max_addr.value_or(default_max_addr)`

Any returned address is guaranteed to be nonzero.

fit::failed is returned if there is insufficient free RAM to track any

new ranges or if there is no free RAM that meets the given constraints.

Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)

Attempts to allocate memory out of free RAM of the prescribed type, size,

and alignment. An optional upper address bound may be passed: if

unspecified the default upper bound passed to Init() will be respected.

`type` must be an allocated type. `size` must be positive and the following

must hold:

`min_addr.value_or(default_min_addr)

<

= max_addr.value_or(default_max_addr)`

Any returned address is guaranteed to be nonzero.

fit::failed is returned if there is insufficient free RAM to track any

new ranges or if there is no free RAM that meets the given constraints.

Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

iterator FindContainingRange (uint64_t addr)

Returns an iterator pointing to the tracked, normalized range containing

the provided address if one exists, or else end().

Defined at line 179 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

iterator FindContainingRange (uint64_t addr)

Returns an iterator pointing to the tracked, normalized range containing

the provided address if one exists, or else end().

Defined at line 179 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

fit::result<fit::failed> MarkAsPeripheral (const memalloc::Range & range)

Returns `fit::success` if the provided range was succesully marked as peripheral. This requires

that `range.type` is `memalloc::Type::kPeripheral` and that there are no ranges of type

`memalloc::Type::kFreeRam` or allocated types overlapping in the range, otherwise `fit::failed`

is returned.

Defined at line 207 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

void PrintMemoryRanges (const char * prefix, FILE * f)

Pretty-prints the memory ranges contained in the pool.

Defined at line 277 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

void PrintMemoryRanges (const char * prefix, FILE * f)

Pretty-prints the memory ranges contained in the pool.

Defined at line 277 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h

fit::result<fit::failed> UpdateRamSubranges (Type type, uint64_t addr, uint64_t size)

Destructively reallocates all RAM types within the given range to the

provided allocated type.

`addr + size` cannot exceed UINT64_MAX.

The utility of this method lies in situations where there is a special

range that we ultimately want to reserve for another booting context that

we are handing pool bookkeeping off to. For example, when loading a

fixed-address kernel image, we would want to prevent page tables - which

must persist across the boot - from being allocated out of that load range.

fit::failed is returned if there is insufficient bookkeeping to track any

new ranges of memory.

Defined at line 563 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> UpdateRamSubranges (Type type, uint64_t addr, uint64_t size)

Destructively reallocates all RAM types within the given range to the

provided allocated type.

`addr + size` cannot exceed UINT64_MAX.

The utility of this method lies in situations where there is a special

range that we ultimately want to reserve for another booting context that

we are handing pool bookkeeping off to. For example, when loading a

fixed-address kernel image, we would want to prevent page tables - which

must persist across the boot - from being allocated out of that load range.

fit::failed is returned if there is insufficient bookkeeping to track any

new ranges of memory.

Defined at line 563 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> Free (uint64_t addr, uint64_t size)

Attempts to free a subrange of a previously allocated range or one of

an allocated type that had previously been passed to Init(). This subrange

is updated to have type kFreeRam.

Freeing a range already tracked as kFreeRam is a no-op.

fit::failed is returned if there is insufficient memory to track the new

(subdivided) ranges of memory that would result from freeing.

Defined at line 408 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> Free (uint64_t addr, uint64_t size)

Attempts to free a subrange of a previously allocated range or one of

an allocated type that had previously been passed to Init(). This subrange

is updated to have type kFreeRam.

Freeing a range already tracked as kFreeRam is a no-op.

fit::failed is returned if there is insufficient memory to track the new

(subdivided) ranges of memory that would result from freeing.

Defined at line 408 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed, uint64_t> Resize (const Range & original, uint64_t new_size, uint64_t min_alignment)

Attempts to resize a previously allocated range or one of the ranges of

allocated type originally passed to Init(). The resizing occurs only at

the level of bookkeeping; the start of the resized region is returned and,

if it differs from the one originally supplied, it is the responsibility

of the caller to actually std::memmove the old contents to the new region

before another allocation is performed. If the new size is smaller than

the original, then this method effectively just frees the range's tail.

The original range - as opposed to just its root address - is required to

be passed in as testimony; since the original allocation or

initialization, the pool may have coalesced neighbouring regions into it

or freed subregions of it, this method asserts that the associated tracked

range does at least still have `original` as a subrange with the

appropriate type. The provided range must also be of allocated type.

`new_size` must be positive; this method is not a backdoor `Free()`. The

original range must already be `min_alignment`-aligned.

fit::failed is returned if there is insufficient memory to track the new

(subdivided) ranges of memory that would result from resizing, or if the

range is untracked. No failure mode will leave the original range freed.

Defined at line 441 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed, uint64_t> Resize (const Range & original, uint64_t new_size, uint64_t min_alignment)

Attempts to resize a previously allocated range or one of the ranges of

allocated type originally passed to Init(). The resizing occurs only at

the level of bookkeeping; the start of the resized region is returned and,

if it differs from the one originally supplied, it is the responsibility

of the caller to actually std::memmove the old contents to the new region

before another allocation is performed. If the new size is smaller than

the original, then this method effectively just frees the range's tail.

The original range - as opposed to just its root address - is required to

be passed in as testimony; since the original allocation or

initialization, the pool may have coalesced neighbouring regions into it

or freed subregions of it, this method asserts that the associated tracked

range does at least still have `original` as a subrange with the

appropriate type. The provided range must also be of allocated type.

`new_size` must be positive; this method is not a backdoor `Free()`. The

original range must already be `min_alignment`-aligned.

fit::failed is returned if there is insufficient memory to track the new

(subdivided) ranges of memory that would result from resizing, or if the

range is untracked. No failure mode will leave the original range freed.

Defined at line 441 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> TruncateTotalRam (uint64_t new_capacity_bytes)

Effectively truncates all of RAM (free or allocated) by allocating all of

it past the provided capacity as type kTruncatedRam. This is used to

simulate physical memory constraints of smaller devices. Any allocations

(including pool bookkeeping) past the cut-off are destructively

reallocated (via UpdateRamSubranges()).

kNvram is excluded from this truncation, as such ranges are special and

are of diagnostic value even when simulating physical memory constraints.

Defined at line 594 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> TruncateTotalRam (uint64_t new_capacity_bytes)

Effectively truncates all of RAM (free or allocated) by allocating all of

it past the provided capacity as type kTruncatedRam. This is used to

simulate physical memory constraints of smaller devices. Any allocations

(including pool bookkeeping) past the cut-off are destructively

reallocated (via UpdateRamSubranges()).

kNvram is excluded from this truncation, as such ranges are special and

are of diagnostic value even when simulating physical memory constraints.

Defined at line 594 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)

This method will generate one peripheral range for every run of consecutive peripheral ranges

the pool knows of. This peripheral range will be aligned to oen of the provided alignments.

Each of the provided alignments is tried, and the first one not to generate invalid ranges,

such as overlapping with free ram ranges, is selected.

`alignments` is a collection of power of two alignments, that is the mask for alignment is

equivalent to `(1

<

<

alignments[n]) - 1`.

Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)

This method will generate one peripheral range for every run of consecutive peripheral ranges

the pool knows of. This peripheral range will be aligned to oen of the provided alignments.

Each of the provided alignments is tried, and the first one not to generate invalid ranges,

such as overlapping with free ram ranges, is selected.

`alignments` is a collection of power of two alignments, that is the mask for alignment is

equivalent to `(1

<

<

alignments[n]) - 1`.

Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)

This method will generate one peripheral range for every run of consecutive peripheral ranges

the pool knows of. This peripheral range will be aligned to oen of the provided alignments.

Each of the provided alignments is tried, and the first one not to generate invalid ranges,

such as overlapping with free ram ranges, is selected.

`alignments` is a collection of power of two alignments, that is the mask for alignment is

equivalent to `(1

<

<

alignments[n]) - 1`.

Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc

fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)

This method will generate one peripheral range for every run of consecutive peripheral ranges

the pool knows of. This peripheral range will be aligned to oen of the provided alignments.

Each of the provided alignments is tried, and the first one not to generate invalid ranges,

such as overlapping with free ram ranges, is selected.

`alignments` is a collection of power of two alignments, that is the mask for alignment is

equivalent to `(1

<

<

alignments[n]) - 1`.

Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc