1.\" $NetBSD: localcount.9,v 1.7 2019/02/25 21:43:00 pgoyette Exp $ 2.\" 3.\" Copyright (c) 2016 The NetBSD Foundation 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Taylor R. Campbell. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd February 25, 2019 31.Dt LOCALCOUNT 9 32.Os 33.Sh NAME 34.Nm localcount , 35.Nm localcount_init , 36.Nm localcount_fini , 37.Nm localcount_acquire , 38.Nm localcount_release , 39.Nm localcount_drain 40.Nd reference-count primitives 41.Sh SYNOPSIS 42.In sys/localcount.h 43.Ft void 44.Fn localcount_init "struct localcount *lc" 45.Ft void 46.Fn localcount_fini "struct localcount *lc" 47.Ft void 48.Fn localcount_acquire "struct localcount *lc" 49.Ft void 50.Fn localcount_release "struct localcount *lc" "struct kcondvar *cv" \ 51"struct kmutex *mtx" 52.Ft void 53.Fn localcount_drain "struct localcount *lc" "struct kcondvar *cv" \ 54"struct kmutex *mtx" 55.Sh DESCRIPTION 56Localcounts are used in the kernel to implement a medium-weight reference 57counting mechanism. 58During normal operations, localcounts do not need the interprocessor 59synchronization associated with 60.Xr atomic_ops 3 61atomic memory operations, and (unlike 62.Xr psref 9 ) 63.Nm 64references can be held across sleeps and can migrate between CPUs. 65Draining a 66.Nm 67requires more expensive interprocessor synchronization than 68.Xr atomic_ops 3 69(similar to 70.Xr psref 9 ) . 71And 72.Nm 73references require eight bytes of memory per object per-CPU, significantly 74more than 75.Xr atomic_ops 3 76and almost always more than 77.Xr psref 9 . 78.Pp 79As a rough heuristic, 80.Nm 81should be used for classes of objects of which there are perhaps a few dozen 82instances (such as 83.Xr autoconf 9 84devices) but not thousands of instances (such as 85network flows) and on which there may be a mixture of long-term I/O waits, 86such as xyzread for a device xyz(4), and short-term fast operations, such as 87.Dv xyzioctl(IOC_READ_A_CPU_REG) . 88.Sh FUNCTIONS 89.Bl -tag -width abcd 90.It Fn localcount_init "lc" 91Dynamically initialize localcount 92.Ar lc 93for use. 94.Pp 95No other operations can be performed on a localcount until it has been 96initialized. 97.It Fn localcount_fini "lc" 98Release resources used by localcount 99.Ar lc . 100The caller must have already called 101.Fn localcount_drain . 102The localcount may not be used after 103.Fn localcount_fini 104has been called until it has been re-initialized by 105.Fn localcount_init . 106.It Fn localcount_acquire "lc" 107Acquire a reference to the localcount 108.Ar lc . 109.Pp 110The caller must ensure by some other mechanism that the localcount will 111not be destroyed before the call to 112.Fn localcount_acquire ; 113typically this will be via a 114.Xr pserialize 9 115read section. 116.It Fn localcount_release "lc" "cv" "mtx" 117Release a reference to the localcount 118.Ar lc . 119If the localcount is currently being drained, the mutex 120.Ar mtx 121will be used to synchronize updates to the global reference count (i.e., 122the total across all CPUs). 123If the reference count goes to zero, 124.Fn localcount_release 125will broadcast availability of the condvar 126.Ar cv . 127.It Fn localcount_drain "lc" "cv" "mtx" 128Wait for all references to the localcount 129.Ar lc 130to be released. 131The caller must hold the mutex 132.Ar mtx ; 133the mutex will be released during inter-CPU cross-calls (see 134.Xr xcall 9 ) 135and while waiting on the condvar 136.Ar cv . 137The same 138.Ar cv 139and 140.Ar mtx 141must be used with 142.Fn localcount_release . 143.Pp 144The caller must guarantee that no new references can be acquired with 145.Fn localcount_acquire 146before calling 147.Fn localcount_drain . 148For example, any object that may be found in a list and acquired must be 149removed from the list before calling 150.Fn localcount_drain ; 151removal from the list would typically be protected by calling 152.Xr pserialize_perform 9 153to wait for any 154.Xr pserialize 9 155readers to complete. 156.Pp 157Once the localcount object 158.Ar lc 159is passed to 160.Fn localcount_drain , 161it must be passed to 162.Fn localcount_fini 163before any other re-use. 164.El 165.Sh CODE REFERENCES 166The core of the localcount implementation is located in 167.Pa sys/kern/subr_localcount.c . 168.Pp 169The header file 170.Pa sys/sys/localcount.h 171describes the public interface, and interfaces that machine-dependent 172code must provide to support localcounts. 173.Sh SEE ALSO 174.Xr atomic_ops 3 , 175.Xr condvar 9 , 176.Xr mutex 9 , 177.Xr psref 9 178.Sh HISTORY 179The localcount primitives first appeared in 180.Nx 8.0 . 181.Sh AUTHORS 182.Nm 183was designed by 184.An -nosplit 185.An Taylor R. Campbell , 186who also provided a draft implementation. 187The implementation was completed, tested, and integrated by 188.An Paul Goyette . 189.Sh CAVEATS 190The 191.Nm 192facility does not provide any way to examine the reference count without 193actually waiting for the count to reach zero. 194.Pp 195Waiting for a 196.Nm 197reference count to drain (reach zero) is a one-shot operation. 198Once the 199.Nm 200has been drained, no further operations are allowed until the 201.Nm 202has been re-initialized. 203