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

NAME


list_create, list_destroy, list_insert_after, list_insert_before,
list_insert_head, list_insert_tail, list_remove, list_remove_head,
list_remove_tail, list_head, list_tail, list_next, list_prev,
list_is_empty,, list_link_init, list_link_active, list_move_tail,
list_link_replace - list functions

SYNOPSIS


#include <sys/list.h>

void
list_create(list_t *list, size_t size, size_t offset);

void
list_destroy(list_t *list);

void
list_insert_after(list_t *list, void *reference_item, void *new_item);

void
list_insert_before(list_t *list, void *reference_item, void *new_item);

void
list_insert_head(list_t *list*, void *new_item);

void
list_insert_tail(list_t *list, void *new_item);

void
list_remove(list_t *list, void *item);

void *
list_remove_head(list_t *list);

void *
list_remove_tail(list_t *list);

void *
list_head(list_t *list);

void *
list_tail(list_t *list);

void *
list_next(list_t *list, void *reference_item);

void *
list_prev(list_t *list, void *reference_item);

int
list_is_empty(list_t *list);

void
list_link_init(list_node_t *node);

int
list_link_active(list_node_t *node);

void
list_move_tail(list_t *dst, list_t *src);

void
list_link_replace(list_node_t *lold, list_node_t *lnew);

DESCRIPTION


These functions provide a generic doubly-linked list implementation.
To utilize it, simply embed a list_node_t field in the structures that
will constitute the linked list elements and pass the list_node_t field
offset to list_create() in the appropriate parameter (see below). A
single list_node_t field can only be used in a single list
simultaneously, so to add a structure to multiple lists, embed multiple
list_node_t fields in your user structure.

Please note that a list_node_t contains pointers back to its parent
list_t so you cannot copy the list_t around once it has been
initialized. In particular, this kind of construct will not work:

struct { list_t l; } a, b;
list_create(&a.l, ...);
b = a; <= This will break the list in `b', as the `l' element
in `a' got copied to a different memory address.

To do this you must move the list items to the new list using functions
such as list_move_tail().

The list_create() function initializes a new list. The driver supplies
the storage for the list handle, the size of an individual element, and
the offset of a list_node_t within the element to use for the links of
the list.

The list_destroy() function destroys the list handle, including freeing
any resources that may have been internally allocated for the list.
The list must be empty when this function is called.

The list_insert_after() and list_insert_before() functions insert
new_item into the linked list at a location after or before the
reference item, which must already be on the list.

The list_insert_head() and list_insert_tail() functions insert the
new_item on the list at either the head or tail of the list. The head
is the first item, the tail is the last item.

The list_remove() function removes the item from the list.

The list_remove_head() and list_remove_tail() functions remove the head
(first) or tail (last) item from the list. The item removed is
returned to the caller. If the list is empty when these functions are
called, then no change is made and NULL is returned to the caller.

The list_head() and list_tail() functions simply return the head
(first) or tail (last) item on the list. NULL is returned if the list
is empty.

The list_next() and list_prev() functions return the next or previous
item in the list, relative to the named reference item which must be
linked on the list. If the referenced item is either the last entry in
the list for list_next() or the first entry in the list for
list_prev(), then the functions will return NULL. This is useful for
iterating over a list with the following pattern:

list_t list_t;
...
for (foo_t *foo = list_head(&list_t); foo != NULL;
foo = list_next(&list_t, foo)) {
/* Process each entry of the list */
}

for (foo_t *foo = list_tail(&list_t); foo != NULL;
foo = list_prev(&list_t, foo)) {
/* Same thing, but in reverse */
}

The list_is_empty() function returns 0 if the list has items in it, or
non-zero otherwise.

The list_link_init() function initializes the list_node_t. It is
functionally equivalent to bzero(node, sizeof (*node));.

The list_link_active() function returns non-zero if the node is on an
active list.

The list_move_tail() function is used to append the items on the src
list to the end of the dst list. It is mandatory that the two lists
were initialized using identical size and offset parameters. Upon
completion, the src list will be empty.

The list_link_replace() function replaces lold node on an active list
with the lnew node. When the function is called the lnew node must not
be linked on any list. Upon completion the lold node will be left
unlinked from any list.

INTERFACE STABILITY


Committed

illumos January 16, 2022 illumos

tribblix@gmail.com :: GitHub :: Privacy