xref: /freebsd/share/man/man9/refcount.9 (revision 7937bfbc0ca53fe7cdd0d54414f9296e273a518e)
1.\"
2.\" Copyright (c) 2009 Hudson River Trading LLC
3.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
4.\" All rights reserved.
5.\"
6.\" Copyright (c) 2019 The FreeBSD Foundation
7.\"
8.\" Parts of this documentation was written by
9.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
10.\" from the FreeBSD Foundation.
11.\"
12.\" Redistribution and use in source and binary forms, with or without
13.\" modification, are permitted provided that the following conditions
14.\" are met:
15.\" 1. Redistributions of source code must retain the above copyright
16.\"    notice, this list of conditions and the following disclaimer.
17.\" 2. Redistributions in binary form must reproduce the above copyright
18.\"    notice, this list of conditions and the following disclaimer in the
19.\"    documentation and/or other materials provided with the distribution.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.Dd October 12, 2022
34.Dt REFCOUNT 9
35.Os
36.Sh NAME
37.Nm refcount ,
38.Nm refcount_init ,
39.Nm refcount_acquire ,
40.Nm refcount_release
41.Nd manage a simple reference counter
42.Sh SYNOPSIS
43.In sys/param.h
44.In sys/refcount.h
45.Ft void
46.Fn refcount_init "volatile u_int *count" "u_int value"
47.Ft u_int
48.Fn refcount_load "volatile u_int *count"
49.Ft u_int
50.Fn refcount_acquire "volatile u_int *count"
51.Ft bool
52.Fn refcount_acquire_checked "volatile u_int *count"
53.Ft bool
54.Fn refcount_acquire_if_not_zero "volatile u_int *count"
55.Ft bool
56.Fn refcount_release "volatile u_int *count"
57.Ft bool
58.Fn refcount_release_if_last "volatile u_int *count"
59.Ft bool
60.Fn refcount_release_if_not_last "volatile u_int *count"
61.Sh DESCRIPTION
62The
63.Nm
64functions provide an API to manage a simple reference counter.
65The caller provides the storage for the counter in an unsigned integer.
66A pointer to this integer is passed via
67.Fa count .
68Usually the counter is used to manage the lifetime of an object and is
69stored as a member of the object.
70.Pp
71Currently all functions are implemented as static inline.
72.Pp
73The
74.Fn refcount_init
75function is used to set the initial value of the counter to
76.Fa value .
77It is normally used when creating a reference-counted object.
78.Pp
79The
80.Fn refcount_load
81function returns a snapshot of the counter value.
82This value may immediately become out-of-date in the absence of external
83synchronization.
84.Fn refcount_load
85should be used instead of relying on the properties of the
86.Vt volatile
87qualifier.
88.Pp
89The
90.Fn refcount_acquire
91function is used to acquire a new reference.
92It returns the counter value before the new reference was acquired.
93The caller is responsible for ensuring that it holds a valid reference
94while obtaining a new reference.
95For example,
96if an object is stored on a list and the list holds a reference on the
97object, then holding a lock that protects the list provides sufficient
98protection for acquiring a new reference.
99.Pp
100The
101.Fn refcount_acquire_checked
102variant performs the same operation as
103.Fn refcount_acquire ,
104but additionally checks that the
105.Fa count
106value does not overflow as result of the operation.
107It returns
108.Dv true
109if the reference was sucessfully obtained, and
110.Dv false
111if it was not, due to the overflow.
112.Pp
113The
114.Fn refcount_acquire_if_not_zero
115function is yet another variant of
116.Fn refcount_acquire ,
117which only obtains the reference when some reference already exists.
118In other words,
119.Fa *count
120must be already greater than zero for the function to succeed, in which
121case the return value is
122.Dv true ,
123otherwise
124.Dv false
125is returned.
126.Pp
127The
128.Fn refcount_release
129function is used to release an existing reference.
130The function returns true if the reference being released was
131the last reference;
132otherwise, it returns false.
133.Pp
134The
135.Fn refcount_release_if_last
136and
137.Fn refcount_release_if_not_last
138functions are variants of
139.Fn refcount_release
140which only drop the reference when it is or is not the last reference,
141respectively.
142In other words,
143.Fn refcount_release_if_last
144returns
145.Dv true
146when
147.Fa *count
148is equal to one, in which case it is decremented to zero.
149Otherwise,
150.Fa *count
151is not modified and the function returns
152.Dv false .
153Similarly,
154.Fn refcount_release_if_not_last
155returns
156.Dv true
157when
158.Fa *count
159is greater than one, in which case
160.Fa *count
161is decremented.
162Otherwise, if
163.Fa *count
164is equal to one, the reference is not released and the function returns
165.Dv false .
166.Pp
167Note that these routines do not provide any inter-CPU synchronization or
168data protection for managing the counter.
169The caller is responsible for any additional synchronization needed by
170consumers of any containing objects.
171In addition,
172the caller is also responsible for managing the life cycle of any containing
173objects including explicitly releasing any resources when the last reference
174is released.
175.Pp
176The
177.Fn refcount_release
178unconditionally executes a release fence (see
179.Xr atomic 9 ) before releasing the reference, which
180synchronizes with an acquire fence executed right before
181returning the
182.Dv true
183value.
184This ensures that the destructor, supposedly executed by the caller after
185the last reference was dropped, sees all updates done during the lifetime
186of the object.
187.Sh RETURN VALUES
188The
189.Nm refcount_release
190function returns true when releasing the last reference and false when
191releasing any other reference.
192.Sh HISTORY
193These functions were introduced in
194.Fx 6.0 .
195