ID_SPACE(9F) Kernel Functions for Drivers ID_SPACE(9F)

NAME


id_space, id_space_create, id_space_destroy, id_space_extend, id_alloc,
id_alloc_nosleep, id_allocff, id_allocff_nosleep,
id_alloc_specific_nosleep, id_free - create, destroy, and use
identifier spaces

SYNOPSIS


#include <sys/id_space.h>

id_space_t *
id_space_create(const char *name, id_t low, id_t high);

void
id_space_destroy(id_space_t *idspace);

void
id_space_extend(id_t low, id_t high);

id_t
id_alloc(id_space_t *idspace);

id_t
id_alloc_nosleep(id_space_t *idspace);

id_t
id_allocff(id_space_t *idspace);

id_t
id_allocff_nosleep(id_space_t *idspace);

id_t
id_allocff_specific_nosleep(id_space_t *idspace, id_t id);

void
id_free(id_space_t *idspace, id_t id);

INTERFACE STABILITY


illumos DDI specific

PARAMETERS


idspace A pointer to an id_space_t structure allocated with the
id_space_create() function.

id An identifier, a signed 32-bit integer.

name An ASCII character string to call the identifier space.

low The lower end of an identifier space. This value is
included in the range.

high The upper end of an identifier space. This value is
excluded from the range.

DESCRIPTION


The id_space suite of functions is used to create and manage identifier
spaces. An identifier space allows the system to manage a range of
identifiers. It tracks what values have been used and which values
have not been used and has different ways of allocating values from the
identifier space.

Identifier spaces are often used by device drivers to manage ranges of
numeric identifiers that may be disjoint. A common use case for
identifier spaces is to manage the set of allocated minor numbers for a
device driver.

Creating, Expanding and Destroying Identifier Spaces
To create an identifier space, the id_space_create() function should be
used. A name for the id space must be passed in the name argument. It
should be unique. For device drivers, often combining the name of the
driver and the instance from the ddi_get_instance(9F) function results
in a unique name.

The values of low and high describe the range of the identifier space.
The range is inclusive on the low end and exclusive on the high end.
Mathematically, this would be represented as [low, high).

Once the id_space_create() function has been successfully called, the
returned identifier space can be used to allocate and manage
identifiers.

Once an identifier space has been created, additional ranges of
identifiers can be added. This process allows for disjoint ranges of
values to be added to a single identifier space. The id_space_extend()
function is used to do this, and it adds the range low to high to the
identifier space. The range follows the same rules as with the
id_space_create() function. It is inclusive of low and is exclusive of
high.

Finally, when an identifier space is no longer being used and all of
its identifiers have been freed, the caller should call the
id_space_destroy() function to destroy the id space idspace.

All three of these functions, id_space_create(), id_space_extend(), and
id_space_destroy() may block. They should only be called from a
context where it's safe for it to block. This is equivalent to
performing a blocking memory allocation.

Allocating Identifiers


Once an id space has been created with the id_space_create() function,
identifiers can be allocated from the space. There are three different
strategies for allocating an identifier:

1. Allocating an identifier using the standard algorithm that
attempts to use the next identifier first.

2. Allocating an identifier using a first fit algorithm. These are
functions with ff in the name. Using this will tend to keep the
allocated id space more compressed.

3. Allocating a specific id.

In addition, identifiers can be allocated in both a blocking and non-
blocking fashion. When functions with the _nosleep prefix are used,
they are non-blocking. If no identifier is available, they will return
an error.

The id_alloc() function will allocate the next identifier. The
id_alloc_nosleep() function uses the same algorithm as id_alloc(), but
will fail rather than block.

The id_allocff() function will allocate the first available identifier.
The id_allocff_nosleep() function uses the same algorithm as
id_allocff(), but will fail rather than block.

The id_alloc_specific_nosleep() function attempts to allocate the
specific identifier id from the specified identifier space. If id has
already been allocated, then the function will fail.

Freeing Identifiers


Every allocated identifier must eventually be freed and returned to the
identifier space. To free an identifier, use the id_free() function,
specifying the identifier in id and the identifier space it came from
in id_space. It is a programmer error to call the id_free() function
on an identifier that has not been allocated.

CONTEXT


All of these functions may be called in user or kernel context. The
id_alloc_nosleep(), id_allocff_nosleep(), and
id_alloc_specific_nosleep() functions may be called in interrupt
context.

RETURN VALUES


Upon successful completion, the id_space_create() function returns a
pointer to an identifier space. Otherwise, NULL is returned to
indicate that the identifier space could not be created.

The id_alloc() and id_allocff() functions always return an identifier
that's in the range of the specified identifier space.

Upon successful completion, the id_alloc_nosleep(),
id_allocff_nosleep(), and id_alloc_specific_nosleep() functions will
return an identifier that's in the range of the specified identifier
space. Otherwise, -1 is returned to indicate that no identifier was
available, or in the case of the id_alloc_specific_nosleep() function,
that the specified identifier was not available.

SEE ALSO


kmem_alloc(9F), rmallocmap(9F)

illumos August 2, 2016 illumos

tribblix@gmail.com :: GitHub :: Privacy