EXTENT(9) BSD Kernel Developer's Manual EXTENT(9)
extent_create, extent_destroy, extent_alloc, extent_alloc_with_descr,
extent_alloc_region, extent_free, extent_print -- general purpose extent
struct extent *
extent_create(char *name, u_long start, u_long end, int mtype,
caddr_t storage, size_t storagesize, int flags);
extent_destroy(struct extent *ex);
extent_alloc(struct extent *ex, u_long size, u_long alignment,
u_long skew, u_long boundary, int flags, u_long *result);
extent_alloc_with_descr(struct extent *ex, u_long size, u_long alignment,
u_long skew, u_long boundary, int flags, struct extent_region *rp,
extent_alloc_subregion(struct extent *ex, u_long substart, u_long subend,
u_long size, u_long alignment, u_long skew, u_long boundary,
int flags, u_long *result);
extent_alloc_subregion_with_descr(struct extent *ex, u_long substart,
u_long subend, u_long size, u_long alignment, u_long skew,
u_long boundary, int flags, struct extent_region *rp,
extent_alloc_region(struct extent *ex, u_long start, u_long size,
extent_free(struct extent *ex, u_long start, u_long size, int flags);
extent_print(struct extent *ex);
The extent manager provides management of areas of memory or other enu-
merable spaces (such as I/O ports). An opaque structure called an extent
map keeps track of allocated regions within the enumerable space.
extent_create() creates an extent map managing the space from start to
end inclusive. All memory allocation will use the memory type mtype (see
malloc(9)). The extent map will have the name name, used for identifica-
tion in case of errors or in ddb(4) show extents. If the flag
EX_NOCOALESCE is set, internal coalescing of regions is disabled, and
only entire regions may be freed within the extent map, so that
extent_free() will never have to allocate a region descriptor. If the
flag EX_FILLED is set, the entire space managed by the extent map will be
allocated upon creation of the extent map, such that selected regions may
be made available through calls to extent_free().
Some applications may want to use an extent map but can't use malloc()
and free(). These applications may provide pre-allocated storage for all
descriptor overhead with the arguments storage and storagesize. An
extent of this type is called a fixed extent. If the application can
safely use malloc() and free(), storage should be NULL. A fixed extent
has a fixed number of region descriptors, so care should be taken to pro-
vide enough storage for them; alternatively, the flag EX_MALLOCOK may be
passed to extent requests to indicate that a fixed extent map may be
extended using a call to malloc(). Note that passing the flag EX_FILLED
to extent_create() will consume a region descriptor upon creation of the
The caller should pass the flag EX_WAITOK or EX_NOWAIT to extent func-
tions that have a memory overhead, to specify whether it is okay to wait.
These functions are extent_create() (non fixed extents), extent_free()
(unless EX_NOCOALESCE is set), extent_alloc(), extent_alloc_subregion()
extent_destroy() destroys the extent map ex, freeing all allocated
regions. If the extent is not a fixed extent, the region and internal
extent descriptors themselves are freed. This function always succeeds.
extent_alloc() allocates a region in the extent map ex of size size that
fits the provided parameters. There are two distinct allocation poli-
cies, which are selected by the flags argument:
EX_FAST Allocate the first region that fits the provided parame-
ters, regardless of resulting extent fragmentation.
default Allocate the smallest region that is capable of holding
the request, thus minimizing fragmentation of the
The caller may specify that it is okay to wait for space to become free
in the extent by setting the flag EX_WAITSPACE. If EX_WAITSPACE is not
set, the allocation will fail if the request can not be satisfied without
The request will be aligned to a multiple of alignment. That value must
be a power of 2. If no alignment is necessary, the value EX_NOALIGN
should be specified. If skew is non-zero, it modifies the requested
alignment result in the following way: the value (result - skew) is
aligned to alignment boundaries. skew must be a smaller number than
alignment. If boundary is not EX_NOBOUNDARY, the allocated region will
not cross any boundary lines, spaced boundary apart. If the caller spec-
ifies the EX_BOUNDZERO flag, boundary lines begin at zero. Otherwise,
boundary lines begin at the beginning of the extent. The allocated
region may begin on a boundary line, but the end of the region will not
touch nor cross a boundary line. A boundary argument smaller than the
sum of the requested skew and the size of the request is invalid. Upon
successful completion, *result will contain the start of the allocated
extent_alloc_with_descr() is similar to extent_alloc() but allows the
caller to provide a pre-allocated region descriptor instead of having the
function allocate one. This function can only be used with extents that
have the EX_NOCOALESCE property.
extent_alloc_subregion() and extent_alloc_subregion_with_descr() are gen-
eralized versions of extent_alloc() and extent_alloc_with_descr() that
allow the caller to specify that the allocated region must fall within
the subregion from substart to subend inclusive.
extent_alloc_region() allocates the specific region in the extent map ex
beginning at start with the size size. If the caller specifies the
EX_CONFLICTOK flag, the allocation will succeed even if part of the
requested region has already been allocated. The caller may specify that
it is okay to wait for the indicated region to be free by setting the
flag EX_WAITSPACE. If neither EX_WAITSPACE nor EX_CONFLICTOK is set, the
allocation will fail if the request can not be satisfied without sleep-
extent_free() frees a region of size bytes starting at start in the
extent map ex. If the extent has the EX_NOCOALESCE property, only entire
regions may be freed. If the extent has the EX_NOCOALESCE property and
the caller attempts to free a partial region, behavior is undefined. If
called on an extent without the EX_NOCOALESCE property, this function can
fail with error codes listed below, otherwise this function will always
extent_print() Prints out information about extent ex. This function
The behavior of all extent manager functions is undefined if given
invalid arguments. extent_create() returns the extent map on success, or
NULL if it fails to allocate storage for the extent map. It always suc-
ceeds when creating a fixed extent or when given the flag EX_WAITOK.
extent_alloc(), extent_alloc_region(), extent_alloc_subregion(), and
extent_free() return one of the following values:
0 Operation was successful.
ENOMEM If EX_NOWAIT is specified, the extent manager was not
able to allocate a region descriptor for the new region
or to split a region when freeing a partial region.
EAGAIN Requested region is not available and EX_WAITSPACE was
EINTR Process received a signal while waiting for the requested
region to become available in the extent.
Here is an example of a (useless) function that uses several of the
extent manager routines.
struct extent *foo_ex;
* Extent "foo" manages a 256k region starting at 0x0 and
* only allows complete regions to be freed so that
* extent_free() never needs to allocate memory.
foo_ex = extent_create("foo", 0x0, 0x3ffff, M_DEVBUF,
NULL, 0, EX_WAITOK | EX_NOCOALESCE);
* Allocate an 8k region, aligned to a 4k boundary, which
* does not cross any of the 3 64k boundaries (at 64k,
* 128k, and 192k) within the extent.
error = extent_alloc(foo_ex, 0x2000, 0x1000, 0x10000,
* Give up the extent.
The extent manager itself is implemented within the file
The i386 bus management code uses the extent manager for managing I/O
ports and I/O memory. See sys/arch/i386/i386/machdep.c.
The extent manager appeared in NetBSD 1.3.
The extent manager was designed and implemented by Jason R. Thorpe
<thorpej@NetBSD.ORG>. Matthias Drochner
<email@example.com> contributed to the initial testing
and optimization of the implementation. Chris Demetriou <cgd@NetBSD.ORG>
contributed many architectural suggestions.
BSD February 8, 2014 BSD