From 3a9bc67fcec1fc09e2c94eaf02f85f607db70edc Mon Sep 17 00:00:00 2001 From: Visa Hankala Date: Tue, 26 Feb 2019 14:28:21 +0000 Subject: Add manual pages for SMR. OK mpi@ sashan@ --- share/man/man9/Makefile | 3 +- share/man/man9/SMR_LIST_INIT.9 | 331 +++++++++++++++++++++++++++++++++++++++++ share/man/man9/SMR_PTR_GET.9 | 69 +++++++++ share/man/man9/smr_call.9 | 124 +++++++++++++++ 4 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 share/man/man9/SMR_LIST_INIT.9 create mode 100644 share/man/man9/SMR_PTR_GET.9 create mode 100644 share/man/man9/smr_call.9 diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index bef3fb94eb4..b55b7baee3c 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.292 2019/02/23 04:54:25 dlg Exp $ +# $OpenBSD: Makefile,v 1.293 2019/02/26 14:28:20 visa Exp $ # $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $ # Makefile for section 9 (kernel function and variable) manual pages. @@ -32,6 +32,7 @@ MAN= aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \ rssadapt.9 route.9 rt_ifa_add.9 rt_timer_add.9 rtalloc.9 rtable_add.9 \ rtlabel_id2name.9 rtrequest.9 rwlock.9 SRPL_EMPTY_LOCKED.9 SipHash24.9 \ sensor_attach.9 sigio_init.9 \ + SMR_LIST_INIT.9 SMR_PTR_GET.9 smr_call.9 \ spl.9 srp_enter.9 srpl_rc_init.9 startuphook_establish.9 \ socreate.9 sosplice.9 strcmp.9 style.9 syscall.9 sysctl_int.9 \ task_add.9 tc_init.9 tfind.9 thread_fork.9 \ diff --git a/share/man/man9/SMR_LIST_INIT.9 b/share/man/man9/SMR_LIST_INIT.9 new file mode 100644 index 00000000000..6b21abf5644 --- /dev/null +++ b/share/man/man9/SMR_LIST_INIT.9 @@ -0,0 +1,331 @@ +.\" $OpenBSD: SMR_LIST_INIT.9,v 1.1 2019/02/26 14:28:20 visa Exp $ +.\" +.\" Copyright (c) 2019 Visa Hankala +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 26 2019 $ +.Dt SMR_LIST_INIT 9 +.Os +.Sh NAME +.Nm SMR_SLIST_ENTRY , +.Nm SMR_SLIST_HEAD , +.Nm SMR_SLIST_HEAD_INITIALIZER , +.Nm SMR_SLIST_INIT , +.Nm SMR_SLIST_FIRST , +.Nm SMR_SLIST_NEXT , +.Nm SMR_SLIST_FOREACH , +.Nm SMR_SLIST_FIRST_LOCKED , +.Nm SMR_SLIST_NEXT_LOCKED , +.Nm SMR_SLIST_EMPTY_LOCKED , +.Nm SMR_SLIST_FOREACH_LOCKED , +.Nm SMR_SLIST_FOREACH_SAFE_LOCKED , +.Nm SMR_SLIST_INSERT_HEAD_LOCKED , +.Nm SMR_SLIST_INSERT_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_HEAD_LOCKED , +.Nm SMR_SLIST_REMOVE_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_LOCKED , +.Nm SMR_LIST_ENTRY , +.Nm SMR_LIST_HEAD , +.Nm SMR_LIST_HEAD_INITIALIZER , +.Nm SMR_LIST_INIT , +.Nm SMR_LIST_FIRST , +.Nm SMR_LIST_NEXT , +.Nm SMR_LIST_FOREACH , +.Nm SMR_LIST_FIRST_LOCKED , +.Nm SMR_LIST_NEXT_LOCKED , +.Nm SMR_LIST_EMPTY_LOCKED , +.Nm SMR_LIST_FOREACH_LOCKED , +.Nm SMR_LIST_FOREACH_SAFE_LOCKED , +.Nm SMR_LIST_INSERT_HEAD_LOCKED , +.Nm SMR_LIST_INSERT_AFTER_LOCKED , +.Nm SMR_LIST_INSERT_BEFORE_LOCKED , +.Nm SMR_LIST_REMOVE_LOCKED +.Nd SMR list macros +.Sh SYNOPSIS +.In sys/smr.h +.Ft void +.Fn SMR_SLIST_INIT "SMR_SLIST_HEAD *head" +.Ft TYPE * +.Fn SMR_SLIST_FIRST "SMR_SLIST_HEAD *head" +.Ft TYPE * +.Fn SMR_SLIST_NEXT "TYPE *elm" "FIELDNAME" +.Fn SMR_SLIST_FOREACH "VARNAME" "SMR_SLIST_HEAD *head" "FIELDNAME" +.Ft TYPE * +.Fn SMR_SLIST_FIRST_LOCKED "SMR_SLIST_HEAD *head" +.Ft TYPE * +.Fn SMR_SLIST_NEXT_LOCKED "TYPE *elm" "FIELDNAME" +.Ft int +.Fn SMR_SLIST_EMPTY_LOCKED "SMR_SLIST_HEAD *head" +.Fn SMR_SLIST_FOREACH_LOCKED "VARNAME" "SMR_SLIST_HEAD *head" "FIELDNAME" +.Fn SMR_SLIST_FOREACH_SAFE_LOCKED "VARNAME" "SMR_LIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME" +.Ft void +.Fn SMR_SLIST_INSERT_HEAD_LOCKED "SMR_SLIST_HEAD *head" "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_SLIST_INSERT_AFTER_LOCKED "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_SLIST_REMOVE_HEAD_LOCKED "SMR_SLIST_HEAD *head" "FIELDNAME" +.Ft void +.Fn SMR_SLIST_REMOVE_AFTER_LOCKED "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_SLIST_REMOVE_LOCKED "SMR_SLIST_HEAD *head" "struct TYPE *elm" "TYPE" "FIELDNAME" +.Ft void +.Fn SMR_LIST_INIT "SMR_LIST_HEAD *head" +.Ft TYPE * +.Fn SMR_LIST_FIRST "SMR_LIST_HEAD *head" +.Ft TYPE * +.Fn SMR_LIST_NEXT "TYPE *elm" "FIELDNAME" +.Ft TYPE * +.Fn SMR_LIST_FIRST_LOCKED "SMR_LIST_HEAD *head" +.Ft TYPE * +.Fn SMR_LIST_NEXT_LOCKED "TYPE *elm" "FIELDNAME" +.Ft int +.Fn SMR_LIST_EMPTY_LOCKED "SMR_LIST_HEAD *head" +.Fn SMR_LIST_FOREACH "VARNAME" "SMR_LIST_HEAD *head" "FIELDNAME" +.Fn SMR_LIST_FOREACH_LOCKED "VARNAME" "SMR_LIST_HEAD *head" "FIELDNAME" +.Fn SMR_LIST_FOREACH_SAFE_LOCKED "VARNAME" "SMR_LIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME" +.Ft void +.Fn SMR_LIST_INSERT_HEAD_LOCKED "SMR_LIST_HEAD *head" "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_LIST_INSERT_AFTER_LOCKED "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_LIST_INSERT_BEFORE_LOCKED "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" +.Ft void +.Fn SMR_LIST_REMOVE_LOCKED "struct TYPE *elm" "FIELDNAME" +.Sh DESCRIPTION +The SMR list macros define and operate on singly-linked lists and lists +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. +.Pp +Readers have to access the data structure inside SMR read-side critical +section. +The critical section is entered using +.Xr smr_read_enter 9 , +and left using +.Xr smr_read_leave 9 . +.Pp +Writers must ensure exclusive write access. +That can be done using a lock, such as +.Xr mutex 9 +or +.Xr rwlock 9 . +The mutual exclusion of writers does not need to apply to readers. +.Pp +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 +.Xr smr_barrier 9 +or +.Xr smr_call 9 +to ensure that the element can no longer be accessed by readers. +.Sh SINGLY-LINKED LISTS +.Fn SMR_SLIST_INIT +initialies the list +.Fa head +to an empty state. +.Pp +.Fn SMR_SLIST_FIRST +and +.Fn SMR_SLIST_FIRST_LOCKED +return the first element on the list +.Fa head , +or NULL if the list is empty. +.Pp +.Fn SMR_SLIST_NEXT +and +.Fn SMR_SLIST_NEXT_LOCKED +return the successor of the element +.Fa elm , +or NULL if there are no more elements on the list. +.Pp +.Fn SMR_SLIST_EMPTY_LOCKED +returns true of the list +.Fa head +is empty. +.Pp +.Fn SMR_SLIST_FOREACH +and +.Fn SMR_SLIST_FOREACH_LOCKED +traverse the list +.Fa head +in forward direction. +.Pp +.Fn SMR_SLIST_FOREACH_SAFE_LOCKED +traverses the list +.Fa head +in forward direction. +It is permitted to remove the element referenced by variable +.Fa VARNAME +from the list and defer its freeing using +.Xr smr_call 9 . +.Pp +.Fn SMR_SLIST_INSERT_HEAD_LOCKED +inserts the new element +.Fa elm +at the head of the list. +.Pp +.Fn SMR_SLIST_INSERT_AFTER_LOCKED +inserts the new element +.Fa elm +after the element +.Fa listelm . +.Pp +.Fn SMR_SLIST_REMOVE_HEAD_LOCKED +removes the first element of the list +.Fa head . +.Pp +.Fn SMR_SLIST_REMOVE_AFTER_LOCKED +removes the list element immediately following +.Fa elm . +.Pp +.Fn SMR_SLIST_REMOVE_LOCKED +removes the list element +.Fa elm +from the list +.Fa head . +.Sh LISTS +.Fn SMR_LIST_INIT +initialies the list +.Fa head +to an empty state. +.Pp +.Fn SMR_LIST_FIRST +and +.Fn SMR_LIST_FIRST_LOCKED +return the first element on the list +.Fa head , +or NULL if the list is empty. +.Pp +.Fn SMR_LIST_NEXT +and +.Fn SMR_LIST_NEXT_LOCKED +return the successor of the element +.Fa elm , +or NULL if there are no more elements on the list. +.Pp +.Fn SMR_SLIST_EMPTY_LOCKED +returns true of the list +.Fa head +is empty. +.Pp +.Fn SMR_LIST_FOREACH +and +.Fn SMR_LIST_FOREACH_LOCKED +traverse the list +.Fa head +in forward direction. +.Pp +.Fn SMR_LIST_FOREACH_SAFE_LOCKED +traverses the list +.Fa head +in forward direction. +It is permitted to remove the element referenced by variable +.Fa VARNAME +from the list and defer its freeing using +.Xr smr_call 9 . +.Pp +.Fn SMR_LIST_INSERT_HEAD_LOCKED +inserts the new element +.Fa elm +at the head of the list. +.Pp +.Fn SMR_LIST_INSERT_AFTER_LOCKED +inserts the new element +.Fa elm +after the element +.Fa listelm . +.Pp +.Fn SMR_LIST_INSERT_BEFORE_LOCKED +inserts the new element +.Fa elm +before the element +.Fa listelm . +.Pp +.Fn SMR_LIST_REMOVE_LOCKED +removes the element +.Fa elm +from the list +.Fa head . +.Sh CONTEXT +.Nm SMR_SLIST_FIRST , +.Nm SMR_SLIST_NEXT , +.Nm SMR_SLIST_FOREACH , +.Nm SMR_SLIST_INIT , +.Nm SMR_SLIST_FIRST_LOCKED , +.Nm SMR_SLIST_NEXT_LOCKED , +.Nm SMR_SLIST_EMPTY_LOCKED , +.Nm SMR_SLIST_FOREACH_LOCKED , +.Nm SMR_SLIST_FOREACH_SAFE_LOCKED , +.Nm SMR_SLIST_INSERT_HEAD_LOCKED , +.Nm SMR_SLIST_INSERT_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_HEAD_LOCKED , +.Nm SMR_SLIST_REMOVE_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_LOCKED , +.Nm SMR_LIST_FIRST , +.Nm SMR_LIST_NEXT , +.Nm SMR_LIST_FOREACH , +.Nm SMR_LIST_INIT , +.Nm SMR_LIST_FIRST_LOCKED , +.Nm SMR_LIST_NEXT_LOCKED , +.Nm SMR_LIST_EMPTY_LOCKED , +.Nm SMR_LIST_FOREACH_LOCKED , +.Nm SMR_LIST_FOREACH_SAFE_LOCKED , +.Nm SMR_LIST_INSERT_HEAD_LOCKED , +.Nm SMR_LIST_INSERT_AFTER_LOCKED , +.Nm SMR_LIST_INSERT_BEFORE_LOCKED +and +.Nm SMR_LIST_REMOVE_LOCKED +can be used during autoconf, from process context, +or from interrupt context. +.Pp +.Nm SMR_SLIST_FIRST , +.Nm SMR_SLIST_NEXT , +.Nm SMR_SLIST_FOREACH , +.Nm SMR_LIST_FIRST , +.Nm SMR_LIST_NEXT +and +.Nm SMR_LIST_FOREACH +can be used from SMR read-side critical section. +.Pp +.Nm SMR_SLIST_INIT , +.Nm SMR_SLIST_FIRST_LOCKED , +.Nm SMR_SLIST_NEXT_LOCKED , +.Nm SMR_SLIST_EMPTY_LOCKED , +.Nm SMR_SLIST_FOREACH_LOCKED , +.Nm SMR_SLIST_FOREACH_SAFE_LOCKED , +.Nm SMR_SLIST_INSERT_HEAD_LOCKED , +.Nm SMR_SLIST_INSERT_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_HEAD_LOCKED , +.Nm SMR_SLIST_REMOVE_AFTER_LOCKED , +.Nm SMR_SLIST_REMOVE_LOCKED , +.Nm SMR_LIST_INIT , +.Nm SMR_LIST_FIRST_LOCKED , +.Nm SMR_LIST_NEXT_LOCKED , +.Nm SMR_LIST_EMPTY_LOCKED , +.Nm SMR_LIST_FOREACH_LOCKED , +.Nm SMR_LIST_FOREACH_SAFE_LOCKED , +.Nm SMR_LIST_INSERT_HEAD_LOCKED , +.Nm SMR_LIST_INSERT_AFTER_LOCKED , +.Nm SMR_LIST_INSERT_BEFORE_LOCKED +and +.Nm SMR_LIST_REMOVE_LOCKED +can be used from writer context. +.Sh SEE ALSO +.Xr queue 3 , +.Xr smr_call 9 , +.Xr smr_read_enter 9 +.Sh HISTORY +The SMR list macros first appeared in +.Ox 6.5 . diff --git a/share/man/man9/SMR_PTR_GET.9 b/share/man/man9/SMR_PTR_GET.9 new file mode 100644 index 00000000000..b607891e85f --- /dev/null +++ b/share/man/man9/SMR_PTR_GET.9 @@ -0,0 +1,69 @@ +.\" $OpenBSD: SMR_PTR_GET.9,v 1.1 2019/02/26 14:28:20 visa Exp $ +.\" +.\" Copyright (c) 2019 Visa Hankala +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 26 2019 $ +.Dt SMR_PTR_GET 9 +.Os +.Sh NAME +.Nm SMR_PTR_GET , +.Nm SMR_PTR_GET_LOCKED , +.Nm SMR_PTR_SET_LOCKED +.Nd safe memory reclamation pointer API +.Sh SYNOPSIS +.Ft TYPE +.Fn SMR_PTR_GET "TYPE *pptr" +.Ft TYPE +.Fn SMR_PTR_GET_LOCKED "TYPE *pptr" +.Ft void +.Fn SMR_PTR_SET_LOCKED "TYPE *pptr" "TYPE value" +.Sh DESCRIPTION +The SMR_PTR macros are used for accessing SMR-protected pointers. +.Pp +The macro +.Fn SMR_PTR_GET +reads the pointer referenced by +.Fa pptr +for dereferencing inside SMR read-side critical section. +.Pp +.Fn SMR_PTR_GET_LOCKED +reads the pointer referenced by +.Fa pptr +for dereferencing inside writer context. +.Pp +.Fn SMR_PTR_SET_LOCKED +writes value +.Fa value +to the pointer referenced by +.Fa pptr . +The operation issues a write-write memory barrier before the pointer write. +.Sh CONTEXT +.Fn SMR_PTR_GET , +.Fn SMR_PTR_GET_LOCKED +and +.Fn SMR_PTR_SET_LOCKED +can be called during autoconf, from process context, or from interrupt context. +.Pp +.Fn SMR_PTR_GET +can be used from SMR read-side critical section. +.Fn SMR_PTR_GET_LOCKED +and +.Fn SMR_PTR_SET_LOCKED +can be used from writer context. +.Sh SEE ALSO +.Xr smr_read_enter 9 +.Sh HISTORY +The SMR_PTR macros first appeared in +.Ox 6.5 . diff --git a/share/man/man9/smr_call.9 b/share/man/man9/smr_call.9 new file mode 100644 index 00000000000..fac24666075 --- /dev/null +++ b/share/man/man9/smr_call.9 @@ -0,0 +1,124 @@ +.\" $OpenBSD: smr_call.9,v 1.1 2019/02/26 14:28:20 visa Exp $ +.\" +.\" Copyright (c) 2019 Visa Hankala +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 26 2019 $ +.Dt SMR_CALL 9 +.Os +.Sh NAME +.Nm smr_read_enter , +.Nm smr_read_leave , +.Nm smr_init , +.Nm smr_call , +.Nm smr_barrier , +.Nm smr_flush , +.Nm SMR_ASSERT_CRITICAL , +.Nm SMR_ASSERT_NONCRITICAL +.Nd safe memory reclamation +.Sh SYNOPSIS +.In sys/smr.h +.Ft void +.Fn smr_read_enter +.Ft void +.Fn smr_read_leave +.Ft void +.Fn smr_init "struct smr_entry *smr" +.Ft void +.Fn smr_call "struct smr_entry *smr" "void (*fn)(void *)" "void *arg" +.Ft void +.Fn smr_barrier +.Ft void +.Fn smr_flush +.Ft void +.Fn SMR_ASSERT_CRITICAL +.Ft void +.Fn SMR_ASSERT_NONCRITICAL +.Sh DESCRIPTION +The safe memory reclamation API provides a mechanism for reclaiming +shared objects that readers can access without locking. +Objects that are reclaimed through SMR are called SMR-protected. +The mechanism guarantees that SMR-protected objects are not destroyed +while readers are using them. +However, it does not control how these objects are modified. +.Pp +Readers access SMR-protected objects inside SMR read-side critical section. +The section is entered with +.Fn smr_read_enter , +and exited with +.Fn smr_read_leave . +These routines never block. +Sleeping is not allowed within SMR read-side critical section. +.Pp +.Fn smr_init +initializes the entry +.Fa smr +for use with +.Fn smr_call . +.Pp +.Fn smr_call +schedules a callback to be invoked after the entry +.Fa smr +cannot be referenced by a reader in SMR read-side critical section. +On invocation, the system calls function +.Fa fn +with argument +.Fa arg +in process context without any locks held. +The implementation may delay the call in order to reduce +overall system overhead by amortization. +.Pp +.Fn smr_barrier +sleeps until any SMR read-side critical sections that are active on other CPUs +at the time of invocation have ended. +Like with +.Fn smr_call , +the processing of the request may be delayed. +.Pp +.Fn smr_flush +is like +.Fn smr_barrier +but the system is forced to process the request as soon as possible. +The use of this function is discouraged because of the heavy impact +on system performance. +.Pp +The SMR implementation does not limit the number of deferred calls. +It is important to prevent arbitrary call rate of +.Fn smr_call . +Otherwise, it might be possible to exhaust system resources +if the system is not able to invoke callbacks quickly enough. +.Pp +.Fn SMR_ASSERT_CRITICAL +and +.Fn SMR_ASSERT_NONCRITICAL +can be used to assert that the current CPU is or is not +in SMR read-side critical section. +.Sh CONTEXT +.Fn smr_read_enter , +.Fn smr_read_leave , +.Fn smr_call +and +.Fn smr_init +can be called during autoconf, from process context, or from interrupt context. +.Pp +.Fn smr_barrier +and +.Fn smr_flush +can be called during autoconf, or from process context. +.Sh SEE ALSO +.Xr mutex 9 , +.Xr rwlock 9 +.Sh HISTORY +The SMR API first appeared in +.Ox 6.5 . -- cgit v1.2.3