xref: /netbsd-src/share/man/man9/localcount.9 (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1.\"	$NetBSD: localcount.9,v 1.6 2017/06/02 00:32:12 chs 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 June 1, 2017
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 32n
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.It Fn localcount_release "lc" "cv" "mtx"
110Release a reference to the localcount
111.Ar lc .
112If the localcount is currently being drained, the mutex
113.Ar mtx
114will be used to synchronize updates to the global reference count (i.e.,
115the total across all CPUs).
116If the reference count goes to zero,
117.Fn localcount_release
118will broadcast availability of the condvar
119.Ar cv .
120.It Fn localcount_drain "lc" "cv" "mtx"
121Wait for all references to the localcount
122.Ar lc
123to be released.
124The caller must hold the mutex
125.Ar mtx ;
126the mutex will be released during inter-CPU cross-calls (see
127.Xr xcall 9 )
128and while waiting on the condvar
129.Ar cv .
130The same
131.Ar cv
132and
133.Ar mtx
134must be used with
135.Fn localcount_release .
136.Pp
137The caller must guarantee that no new references can be acquired with
138.Fn localcount_acquire
139before calling
140.Fn localcount_drain .
141For example, any object that may be found in a list and acquired must be
142removed from the list before calling
143.Fn localcount_drain .
144Once the localcount object
145.Ar lc
146is passed to
147.Fn localcount_drain ,
148it must be passed to
149.Fn localcount_fini
150before any other re-use.
151.El
152.Sh CODE REFERENCES
153The core of the localcount implementation is located in
154.Pa sys/kern/subr_localcount.c .
155.Pp
156The header file
157.Pa sys/sys/localcount.h
158describes the public interface, and interfaces that machine-dependent
159code must provide to support localcounts.
160.Sh SEE ALSO
161.Xr atomic_ops 3 ,
162.Xr condvar 9 ,
163.Xr mutex 9 ,
164.Xr psref 9
165.Sh HISTORY
166The localcount primitives first appeared in
167.Nx 8.0 .
168.Sh AUTHORS
169.Nm
170was designed by
171.An -nosplit
172.An Taylor R. Campbell ,
173who also provided a draft implementation.
174The implementation was completed, tested, and integrated by
175.An Paul Goyette .
176.Sh CAVEATS
177The
178.Nm
179facility does not provide any way to examine the reference count without
180actually waiting for the count to reach zero.
181.Pp
182Waiting for a
183.Nm
184reference count to drain (reach zero) is a one-shot operation.
185Once the
186.Nm
187has been drained, no further operations are allowed until the
188.Nm
189has been re-initialized.
190