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