1.\" $OpenBSD: srpl_rc_init.9,v 1.10 2016/05/18 03:46:03 dlg Exp $ 2.\" 3.\" Copyright (c) 2015 David Gwynne <dlg@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: May 18 2016 $ 18.Dt SRPL_RC_INIT 9 19.Os 20.Sh NAME 21.Nm srpl_rc_init , 22.Nm SRPL_HEAD , 23.Nm SRPL_ENTRY , 24.Nm SRPL_INIT , 25.Nm SRPL_ENTER , 26.Nm SRPL_NEXT , 27.Nm SRPL_FOREACH , 28.Nm SRPL_LEAVE , 29.Nm SRPL_EMPTY_LOCKED , 30.Nm SRPL_FIRST_LOCKED , 31.Nm SRPL_NEXT_LOCKED , 32.Nm SRPL_FOREACH_LOCKED , 33.Nm SRPL_FOREACH_SAFE_LOCKED , 34.Nm SRPL_INSERT_HEAD_LOCKED , 35.Nm SRPL_INSERT_AFTER_LOCKED , 36.Nm SRPL_REMOVE_LOCKED , 37.Nm SRPL_RC_INITIALIZER 38.Nd singly-linked shared reference pointer list 39.Sh SYNOPSIS 40.In sys/srp.h 41.Vt struct srpl_rc; 42.Ft void 43.Fo "srpl_rc_init" 44.Fa "struct srpl_rc *rc" 45.Fa "void (*ref)(void *, void *)" 46.Fa "void (*unref)(void *, void *)" 47.Fa "void *ctx" 48.Fc 49.Fn SRPL_HEAD "HEADNAME" "TYPE" 50.Fn SRPL_ENTRY "TYPE" 51.Fn "SRPL_INIT" "SRPL_HEAD *sl" 52.Ft void * 53.Fn "SRPL_ENTER" "struct srp_ref *sr" "SRPL_HEAD *sl" 54.Ft void * 55.Fn "SRPL_NEXT" "struct srp_ref *sr" "struct TYPE *listelm" "FIELDNAME" 56.Fo "SRPL_FOREACH" 57.Fa "VARNAME" 58.Fa "struct srp_ref *sr" 59.Fa "SRPL_HEAD *sl" 60.Fa "FIELDNAME" 61.Fc 62.Fn "SRPL_LEAVE" "struct srp_ref *sr" 63.Fn "SRPL_EMPTY_LOCKED" "SRPL_HEAD *sl" 64.Ft void * 65.Fn "SRPL_FIRST_LOCKED" "SRPL_HEAD *sl" 66.Ft void * 67.Fn "SRPL_NEXT_LOCKED" "struct TYPE *listelm" "FIELDNAME" 68.Fn "SRPL_FOREACH_LOCKED" "VARNAME" "SRPL_HEAD *sl" "FIELDNAME" 69.Fn "SRPL_FOREACH_SAFE_LOCKED" "VARNAME" "SRPL_HEAD *sl" "FIELDNAME" "TEMP_VARNAME" 70.Fo "SRPL_INSERT_HEAD_LOCKED" 71.Fa "struct srpl_rc *rc" 72.Fa "SRPL_HEAD *sl" 73.Fa "struct TYPE *elm" 74.Fa "FIELDNAME" 75.Fc 76.Fo "SRPL_INSERT_AFTER_LOCKED" 77.Fa "struct srpl_rc *rc" 78.Fa "struct TYPE *listelm" 79.Fa "struct TYPE *elm" 80.Fa "FIELDNAME" 81.Fc 82.Fo "SRPL_REMOVE_LOCKED" 83.Fa "struct srpl_rc *rc" 84.Fa "SRPL_HEAD *sl" 85.Fa "struct TYPE *listelm" 86.Fa "TYPE" 87.Fa "FIELDNAME" 88.Fc 89.Fo "SRPL_RC_INITIALIZER" 90.Fa "void (*ref)(void *, void *)" 91.Fa "void (*unref)(void *, void *)" 92.Fa "void *ctx" 93.Fc 94.Sh DESCRIPTION 95The 96srpl 97macros build a linked list on top of shared reference pointers. 98This allows concurrent traversal of a linked list and access to the 99items on the list. 100.Pp 101SRP lists are a generic type represented by a 102.Vt SRPL_HEAD . 103The elements inserted into the list must be structures that contain a 104.Vt SRPL_ENTRY 105field. 106Further, the elements must also support reference counting as 107insertion and removal operations can cause items to be temporarily 108referenced by multiple SRPs within the list at the same time. 109.Pp 110.Fn srpl_rc_init 111initialises the SRP list refcounts 112.Fa rc 113structure so it can be used to manage the reference counts on 114elements in the list. 115The insertion or removal of an element in an SRP list will increment 116the reference counts on elements within the list via calls to 117.Fa ref . 118As these references are released by the SRP infrastructure, the 119reference counts will be decremented by calls to 120.Fa unref . 121.Fa unref 122is also responsible for freeing the element when the reference count 123reaches 0. 124Both 125.Fa ref 126and 127.Fa unref 128will be called with 129.Fa ctx 130as their first argument and a pointer to the element as their second 131argument. 132.Pp 133.Fn SRPL_INIT 134initialises the SRP list 135.Fa sl 136to an empty state. 137.Pp 138.Fn SRPL_ENTER 139begins iterating over elements in the SRP list 140.Fa sl . 141The reference to the list item is held via 142.Fa sr . 143Every call to 144.Fn SRPL_ENTER 145must have a corresponding call to 146.Fn SRPL_LEAVE 147to release references to the list and its elements. 148.Pp 149.Fn SRPL_NEXT 150accesses the element in the SRP list after 151.Fa listelm . 152.Pp 153.Fn SRPL_FOREACH 154creates a loop for traversing the list. 155Every call to 156.Fn SRPL_FOREACH 157must have a corresponding call to 158.Fn SRPL_LEAVE 159to release references to the list and its elements. 160.Pp 161.Fn SRPL_LEAVE 162releases references to the list and its elements held by previous 163calls to 164.Fn SRPL_ENTER , 165.Fn SRPL_NEXT , 166or 167.Fn SRPL_FOREACH . 168.Pp 169.Fn SRPL_EMPTY_LOCKED 170tests whether the SRP list 171.Fa sl 172is empty. 173.Pp 174.Fn SRPL_FIRST_LOCKED 175accesses the first element in the SRP list 176.Fa sl . 177.Pp 178.Fn SRPL_NEXT_LOCKED 179accesses the next element in the SRP list after 180.Fa listelm . 181.Pp 182.Fn SRPL_FOREACH_LOCKED 183creates a loop for traversing the elements in the SRP list 184.Fa sl . 185.Pp 186.Fn SRPL_FOREACH_SAFE_LOCKED 187creates a loop for traversing the elements in the SRP list 188.Fa sl , 189permitting it to remove 190.Fa VARNAME 191as well as freeing it from within the loop safely without interfering with the 192traversal. 193.Pp 194.Fn SRPL_INSERT_HEAD_LOCKED 195inserts 196.Fa elm 197into the SRP list 198.Fa sl . 199Reference counts are adjusted on the list items using the functions 200specified by 201.Fa rc . 202.Pp 203.Fn SRPL_INSERT_AFTER_LOCKED 204inserts 205.Fa elm 206into an SRP list after the element 207.Fa listelm . 208Reference counts are adjusted on the list items using the functions 209specified by 210.Fa rc . 211.Pp 212.Fn SRPL_REMOVE_LOCKED 213iterates over the SRP list 214.Fa sl 215until it finds 216.Fa listelm 217and then removes it. 218Reference counts are adjusted on the list items using the functions 219specified by 220.Fa rc . 221.Pp 222An srpl_rc declaration can be initialised with the 223.Fn SRPL_RC_INITIALIZER 224macro. 225.Sh CONTEXT 226.Fn SRPL_INIT , 227.Fn SRPL_ENTER , 228.Fn SRPL_NEXT , 229.Fn SRPL_FOREACH , 230and 231.Fn SRPL_LEAVE 232may be called during autoconf, from process context, or from interrupt 233context. 234.Pp 235.Fn srpl_rc_init , 236.Fn SRPL_EMPTY_LOCKED , 237.Fn SRPL_FIRST_LOCKED , 238.Fn SRPL_NEXT_LOCKED , 239.Fn SRPL_FOREACH_LOCKED , 240.Fn SRPL_INSERT_HEAD_LOCKED , 241.Fn SRPL_INSERT_AFTER_LOCKED , 242and 243.Fn SRPL_REMOVE_LOCKED 244may be called during autoconf or from process context. 245An appropriate lock must be held that prevents concurrent modifications 246to the list. 247.Sh RETURN VALUES 248.Fn SRPL_ENTER , 249.Fn SRPL_NEXT , 250.Fn SRPL_FIRST_LOCKED , 251and 252.Fn SRPL_NEXT_LOCKED 253return a pointer to elements in the SRP list, or 254.Dv NULL 255if there are no more elements. 256.Pp 257.Fn SRPL_EMPTY_LOCKED 258returns non-zero when the list is empty, otherwise 0. 259.Sh HISTORY 260The srp API was originally written by 261.An Jonathan Matthew Aq Mt jmatthew@openbsd.org 262and 263.An David Gwynne Aq Mt dlg@openbsd.org . 264The SRP list API first appeared in 265.Ox 5.9 . 266