Manual Page Result
0
Command: SMR_LIST_INIT | Section: 9 | Source: OpenBSD | File: SMR_LIST_INIT.9
SMR_LIST_INIT(9) FreeBSD Kernel Developer's Manual SMR_LIST_INIT(9)
NAME
SMR_SLIST_ENTRY, SMR_SLIST_HEAD, SMR_SLIST_HEAD_INITIALIZER,
SMR_SLIST_INIT, SMR_SLIST_FIRST, SMR_SLIST_NEXT, SMR_SLIST_FOREACH,
SMR_SLIST_FIRST_LOCKED, SMR_SLIST_NEXT_LOCKED, SMR_SLIST_EMPTY_LOCKED,
SMR_SLIST_FOREACH_LOCKED, SMR_SLIST_FOREACH_SAFE_LOCKED,
SMR_SLIST_INSERT_HEAD_LOCKED, SMR_SLIST_INSERT_AFTER_LOCKED,
SMR_SLIST_REMOVE_HEAD_LOCKED, SMR_SLIST_REMOVE_AFTER_LOCKED,
SMR_SLIST_REMOVE_LOCKED, SMR_LIST_ENTRY, SMR_LIST_HEAD,
SMR_LIST_HEAD_INITIALIZER, SMR_LIST_INIT, SMR_LIST_FIRST, SMR_LIST_NEXT,
SMR_LIST_FOREACH, SMR_LIST_FIRST_LOCKED, SMR_LIST_NEXT_LOCKED,
SMR_LIST_EMPTY_LOCKED, SMR_LIST_FOREACH_LOCKED,
SMR_LIST_FOREACH_SAFE_LOCKED, SMR_LIST_INSERT_HEAD_LOCKED,
SMR_LIST_INSERT_AFTER_LOCKED, SMR_LIST_INSERT_BEFORE_LOCKED,
SMR_LIST_REMOVE_LOCKED, SMR_TAILQ_ENTRY, SMR_TAILQ_HEAD,
SMR_TAILQ_HEAD_INITIALIZER, SMR_TAILQ_INIT, SMR_TAILQ_FIRST,
SMR_TAILQ_NEXT, SMR_TAILQ_FOREACH, SMR_TAILQ_FIRST_LOCKED,
SMR_TAILQ_NEXT_LOCKED, SMR_TAILQ_LAST_LOCKED, SMR_TAILQ_EMPTY_LOCKED,
SMR_TAILQ_FOREACH_LOCKED, SMR_TAILQ_FOREACH_SAFE_LOCKED,
SMR_TAILQ_INSERT_HEAD_LOCKED, SMR_TAILQ_INSERT_TAIL_LOCKED,
SMR_TAILQ_INSERT_AFTER_LOCKED, SMR_TAILQ_INSERT_BEFORE_LOCKED,
SMR_TAILQ_REMOVE_LOCKED - SMR list macros
SYNOPSIS
#include <sys/smr.h>
SMR_SLIST_ENTRY(TYPE);
void
SMR_SLIST_INIT(SMR_SLIST_HEAD *head);
TYPE *
SMR_SLIST_FIRST(SMR_SLIST_HEAD *head);
TYPE *
SMR_SLIST_NEXT(TYPE *elm, FIELDNAME);
SMR_SLIST_FOREACH(VARNAME, SMR_SLIST_HEAD *head, FIELDNAME);
TYPE *
SMR_SLIST_FIRST_LOCKED(SMR_SLIST_HEAD *head);
TYPE *
SMR_SLIST_NEXT_LOCKED(TYPE *elm, FIELDNAME);
int
SMR_SLIST_EMPTY_LOCKED(SMR_SLIST_HEAD *head);
SMR_SLIST_FOREACH_LOCKED(VARNAME, SMR_SLIST_HEAD *head, FIELDNAME);
SMR_SLIST_FOREACH_SAFE_LOCKED(VARNAME, SMR_LIST_HEAD *head, FIELDNAME,
TEMP_VARNAME);
void
SMR_SLIST_INSERT_HEAD_LOCKED(SMR_SLIST_HEAD *head, struct TYPE *elm,
FIELDNAME);
void
SMR_SLIST_INSERT_AFTER_LOCKED(struct TYPE *listelm, struct TYPE *elm,
FIELDNAME);
void
SMR_SLIST_REMOVE_HEAD_LOCKED(SMR_SLIST_HEAD *head, FIELDNAME);
void
SMR_SLIST_REMOVE_AFTER_LOCKED(struct TYPE *elm, FIELDNAME);
void
SMR_SLIST_REMOVE_LOCKED(SMR_SLIST_HEAD *head, struct TYPE *elm, TYPE,
FIELDNAME);
SMR_LIST_ENTRY(TYPE);
void
SMR_LIST_INIT(SMR_LIST_HEAD *head);
TYPE *
SMR_LIST_FIRST(SMR_LIST_HEAD *head);
TYPE *
SMR_LIST_NEXT(TYPE *elm, FIELDNAME);
TYPE *
SMR_LIST_FIRST_LOCKED(SMR_LIST_HEAD *head);
TYPE *
SMR_LIST_NEXT_LOCKED(TYPE *elm, FIELDNAME);
int
SMR_LIST_EMPTY_LOCKED(SMR_LIST_HEAD *head);
SMR_LIST_FOREACH(VARNAME, SMR_LIST_HEAD *head, FIELDNAME);
SMR_LIST_FOREACH_LOCKED(VARNAME, SMR_LIST_HEAD *head, FIELDNAME);
SMR_LIST_FOREACH_SAFE_LOCKED(VARNAME, SMR_LIST_HEAD *head, FIELDNAME,
TEMP_VARNAME);
void
SMR_LIST_INSERT_HEAD_LOCKED(SMR_LIST_HEAD *head, struct TYPE *elm,
FIELDNAME);
void
SMR_LIST_INSERT_AFTER_LOCKED(struct TYPE *listelm, struct TYPE *elm,
FIELDNAME);
void
SMR_LIST_INSERT_BEFORE_LOCKED(struct TYPE *listelm, struct TYPE *elm,
FIELDNAME);
void
SMR_LIST_REMOVE_LOCKED(struct TYPE *elm, FIELDNAME);
SMR_TAILQ_ENTRY(TYPE);
void
SMR_TAILQ_INIT(SMR_TAILQ_HEAD *head);
TYPE *
SMR_TAILQ_FIRST(SMR_TAILQ_HEAD *head);
TYPE *
SMR_TAILQ_NEXT(TYPE *elm, FIELDNAME);
TYPE *
SMR_TAILQ_FIRST_LOCKED(SMR_TAILQ_HEAD *head);
TYPE *
SMR_TAILQ_NEXT_LOCKED(TYPE *elm, FIELDNAME);
TYPE *
SMR_TAILQ_LAST_LOCKED(SMR_TAILQ_HEAD *head);
SMR_TAILQ_FOREACH(VARNAME, SMR_TAILQ_HEAD *head, FIELDNAME);
SMR_TAILQ_FOREACH_LOCKED(VARNAME, SMR_TAILQ_HEAD *head, FIELDNAME);
SMR_TAILQ_FOREACH_SAFE_LOCKED(VARNAME, SMR_TAILQ_HEAD *head, FIELDNAME,
TEMP_VARNAME);
void
SMR_TAILQ_INSERT_HEAD_LOCKED(SMR_TAILQ_HEAD *head, struct TYPE *elm,
FIELDNAME);
void
SMR_TAILQ_INSERT_TAIL_LOCKED(SMR_TAILQ_HEAD *head, struct TYPE *elm,
FIELDNAME);
void
SMR_TAILQ_INSERT_AFTER_LOCKED(struct TYPE *listelm, struct TYPE *elm,
FIELDNAME);
void
SMR_TAILQ_INSERT_BEFORE_LOCKED(struct TYPE *listelm, struct TYPE *elm,
FIELDNAME);
void
SMR_TAILQ_REMOVE_LOCKED(struct TYPE *elm, FIELDNAME);
DESCRIPTION
The SMR list macros define and operate on singly-linked lists, lists and
tail queues that can be used with the safe memory reclamation mechanism.
A data structure built with these macros can be accessed concurrently by
multiple readers and a single writer.
Readers have to access the data structure inside SMR read-side critical
section. The critical section is entered using smr_read_enter(9), and
left using smr_read_leave(9).
Writers must ensure exclusive write access. That can be done using a
lock, such as mutex(9) or rwlock(9). The mutual exclusion of writers
does not need to apply to readers.
When an element has been removed from the data structure, the element
must not be deleted or re-inserted before all reader references to it
have disappeared. The writer has to use either smr_barrier(9) or
smr_call(9) to ensure that the element can no longer be accessed by
readers.
Singly-Linked Lists
The SMR_SLIST_ENTRY() macro declares a structure that connects the
elements in the list.
SMR_SLIST_INIT() initializes the list head to an empty state.
SMR_SLIST_FIRST() and SMR_SLIST_FIRST_LOCKED() return the first element
on the list head, or NULL if the list is empty.
SMR_SLIST_NEXT() and SMR_SLIST_NEXT_LOCKED() return the successor of the
element elm, or NULL if there are no more elements on the list.
SMR_SLIST_EMPTY_LOCKED() returns true if the list head is empty.
SMR_SLIST_FOREACH() and SMR_SLIST_FOREACH_LOCKED() traverse the list head
in forward direction.
SMR_SLIST_FOREACH_SAFE_LOCKED() traverses the list head in forward
direction. It is permitted to remove the element referenced by variable
VARNAME from the list and defer its freeing using smr_call(9).
SMR_SLIST_INSERT_HEAD_LOCKED() inserts the new element elm at the head of
the list.
SMR_SLIST_INSERT_AFTER_LOCKED() inserts the new element elm after the
element listelm.
SMR_SLIST_REMOVE_HEAD_LOCKED() removes the first element of the list
head.
SMR_SLIST_REMOVE_AFTER_LOCKED() removes the list element immediately
following elm.
SMR_SLIST_REMOVE_LOCKED() removes the list element elm from the list
head.
Linked Lists
The SMR_LIST_ENTRY() macro declares a structure that connects the
elements in the list.
SMR_LIST_INIT() initializes the list head to an empty state.
SMR_LIST_FIRST() and SMR_LIST_FIRST_LOCKED() return the first element on
the list head, or NULL if the list is empty.
SMR_LIST_NEXT() and SMR_LIST_NEXT_LOCKED() return the successor of the
element elm, or NULL if there are no more elements on the list.
SMR_LIST_EMPTY_LOCKED() returns true if the list head is empty.
SMR_LIST_FOREACH() and SMR_LIST_FOREACH_LOCKED() traverse the list head
in forward direction.
SMR_LIST_FOREACH_SAFE_LOCKED() traverses the list head in forward
direction. It is permitted to remove the element referenced by variable
VARNAME from the list and defer its freeing using smr_call(9).
SMR_LIST_INSERT_HEAD_LOCKED() inserts the new element elm at the head of
the list.
SMR_LIST_INSERT_AFTER_LOCKED() inserts the new element elm after the
element listelm.
SMR_LIST_INSERT_BEFORE_LOCKED() inserts the new element elm before the
element listelm.
SMR_LIST_REMOVE_LOCKED() removes the element elm from the list head.
Tail Queues
The SMR_TAILQ_ENTRY() macro declares a structure that connects the
elements in the tail queue.
SMR_TAILQ_INIT() initializes the tail queue head to an empty state.
SMR_TAILQ_FIRST() and SMR_TAILQ_FIRST_LOCKED() return the first element
in the queue head, or NULL if the queue is empty.
SMR_TAILQ_NEXT() and SMR_TAILQ_NEXT_LOCKED() return the successor of the
element elm, or NULL if there are no more elements in the queue.
SMR_TAILQ_EMPTY_LOCKED() returns true if the queue head is empty.
SMR_TAILQ_FOREACH() and SMR_TAILQ_FOREACH_LOCKED() traverse the queue
head in forward direction.
SMR_TAILQ_FOREACH_SAFE_LOCKED() traverses the queue head in forward
direction. It is permitted to remove the element referenced by variable
VARNAME from the queue and defer its freeing using smr_call(9).
SMR_TAILQ_INSERT_HEAD_LOCKED() inserts the new element elm at the head of
the queue.
SMR_TAILQ_INSERT_TAIL_LOCKED() inserts the new element elm at the tail of
the queue.
SMR_TAILQ_INSERT_AFTER_LOCKED() inserts the new element elm after the
element listelm.
SMR_TAILQ_INSERT_BEFORE_LOCKED() inserts the new element elm before the
element listelm.
SMR_TAILQ_REMOVE_LOCKED() removes the element elm from the queue head.
CONTEXT
All SMR list macros can be used during autoconf, from process context, or
from interrupt context.
SMR_SLIST_FIRST, SMR_SLIST_NEXT, SMR_SLIST_FOREACH, SMR_LIST_FIRST,
SMR_LIST_NEXT, SMR_LIST_FOREACH, SMR_TAILQ_FIRST, SMR_TAILQ_NEXT and
SMR_TAILQ_FOREACH can be used from SMR read-side critical section.
SMR_SLIST_INIT, SMR_SLIST_FIRST_LOCKED, SMR_SLIST_NEXT_LOCKED,
SMR_SLIST_EMPTY_LOCKED, SMR_SLIST_FOREACH_LOCKED,
SMR_SLIST_FOREACH_SAFE_LOCKED, SMR_SLIST_INSERT_HEAD_LOCKED,
SMR_SLIST_INSERT_AFTER_LOCKED, SMR_SLIST_REMOVE_HEAD_LOCKED,
SMR_SLIST_REMOVE_AFTER_LOCKED, SMR_SLIST_REMOVE_LOCKED, SMR_LIST_INIT,
SMR_LIST_FIRST_LOCKED, SMR_LIST_NEXT_LOCKED, SMR_LIST_EMPTY_LOCKED,
SMR_LIST_FOREACH_LOCKED, SMR_LIST_FOREACH_SAFE_LOCKED,
SMR_LIST_INSERT_HEAD_LOCKED, SMR_LIST_INSERT_AFTER_LOCKED,
SMR_LIST_INSERT_BEFORE_LOCKED, SMR_LIST_REMOVE_LOCKED, SMR_TAILQ_INIT,
SMR_TAILQ_FIRST_LOCKED, SMR_TAILQ_NEXT_LOCKED, SMR_TAILQ_EMPTY_LOCKED,
SMR_TAILQ_FOREACH_LOCKED, SMR_TAILQ_FOREACH_SAFE_LOCKED,
SMR_TAILQ_INSERT_HEAD_LOCKED, SMR_TAILQ_INSERT_TAIL_LOCKED,
SMR_TAILQ_INSERT_AFTER_LOCKED, SMR_TAILQ_INSERT_BEFORE_LOCKED, and
SMR_TAILQ_REMOVE_LOCKED can be used from writer context.
SEE ALSO
queue(3), smr_call(9), SMR_PTR_GET(9)
HISTORY
The SMR list macros first appeared in OpenBSD 6.5.
FreeBSD 14.1-RELEASE-p8 January 16, 2022 FreeBSD 14.1-RELEASE-p8