xref: /freebsd/share/man/man9/refcount.9 (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
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, Inc.
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.\" $FreeBSD$
34.\"
35.Dd October 12, 2022
36.Dt REFCOUNT 9
37.Os
38.Sh NAME
39.Nm refcount ,
40.Nm refcount_init ,
41.Nm refcount_acquire ,
42.Nm refcount_release
43.Nd manage a simple reference counter
44.Sh SYNOPSIS
45.In sys/param.h
46.In sys/refcount.h
47.Ft void
48.Fn refcount_init "volatile u_int *count" "u_int value"
49.Ft u_int
50.Fn refcount_load "volatile u_int *count"
51.Ft u_int
52.Fn refcount_acquire "volatile u_int *count"
53.Ft bool
54.Fn refcount_acquire_checked "volatile u_int *count"
55.Ft bool
56.Fn refcount_acquire_if_not_zero "volatile u_int *count"
57.Ft bool
58.Fn refcount_release "volatile u_int *count"
59.Ft bool
60.Fn refcount_release_if_last "volatile u_int *count"
61.Ft bool
62.Fn refcount_release_if_not_last "volatile u_int *count"
63.Sh DESCRIPTION
64The
65.Nm
66functions provide an API to manage a simple reference counter.
67The caller provides the storage for the counter in an unsigned integer.
68A pointer to this integer is passed via
69.Fa count .
70Usually the counter is used to manage the lifetime of an object and is
71stored as a member of the object.
72.Pp
73Currently all functions are implemented as static inline.
74.Pp
75The
76.Fn refcount_init
77function is used to set the initial value of the counter to
78.Fa value .
79It is normally used when creating a reference-counted object.
80.Pp
81The
82.Fn refcount_load
83function returns a snapshot of the counter value.
84This value may immediately become out-of-date in the absence of external
85synchronization.
86.Fn refcount_load
87should be used instead of relying on the properties of the
88.Vt volatile
89qualifier.
90.Pp
91The
92.Fn refcount_acquire
93function is used to acquire a new reference.
94It returns the counter value before the new reference was acquired.
95The caller is responsible for ensuring that it holds a valid reference
96while obtaining a new reference.
97For example,
98if an object is stored on a list and the list holds a reference on the
99object, then holding a lock that protects the list provides sufficient
100protection for acquiring a new reference.
101.Pp
102The
103.Fn refcount_acquire_checked
104variant performs the same operation as
105.Fn refcount_acquire ,
106but additionally checks that the
107.Fa count
108value does not overflow as result of the operation.
109It returns
110.Dv true
111if the reference was sucessfully obtained, and
112.Dv false
113if it was not, due to the overflow.
114.Pp
115The
116.Fn refcount_acquire_if_not_zero
117function is yet another variant of
118.Fn refcount_acquire ,
119which only obtains the reference when some reference already exists.
120In other words,
121.Fa *count
122must be already greater than zero for the function to succeed, in which
123case the return value is
124.Dv true ,
125otherwise
126.Dv false
127is returned.
128.Pp
129The
130.Fn refcount_release
131function is used to release an existing reference.
132The function returns true if the reference being released was
133the last reference;
134otherwise, it returns false.
135.Pp
136The
137.Fn refcount_release_if_last
138and
139.Fn refcount_release_if_not_last
140functions are variants of
141.Fn refcount_release
142which only drop the reference when it is or is not the last reference,
143respectively.
144In other words,
145.Fn refcount_release_if_last
146returns
147.Dv true
148when
149.Fa *count
150is equal to one, in which case it is decremented to zero.
151Otherwise,
152.Fa *count
153is not modified and the function returns
154.Dv false .
155Similarly,
156.Fn refcount_release_if_not_last
157returns
158.Dv true
159when
160.Fa *count
161is greater than one, in which case
162.Fa *count
163is decremented.
164Otherwise, if
165.Fa *count
166is equal to one, the reference is not released and the function returns
167.Dv false .
168.Pp
169Note that these routines do not provide any inter-CPU synchronization or
170data protection for managing the counter.
171The caller is responsible for any additional synchronization needed by
172consumers of any containing objects.
173In addition,
174the caller is also responsible for managing the life cycle of any containing
175objects including explicitly releasing any resources when the last reference
176is released.
177.Pp
178The
179.Fn refcount_release
180unconditionally executes a release fence (see
181.Xr atomic 9 ) before releasing the reference, which
182synchronizes with an acquire fence executed right before
183returning the
184.Dv true
185value.
186This ensures that the destructor, supposedly executed by the caller after
187the last reference was dropped, sees all updates done during the lifetime
188of the object.
189.Sh RETURN VALUES
190The
191.Nm refcount_release
192function returns true when releasing the last reference and false when
193releasing any other reference.
194.Sh HISTORY
195These functions were introduced in
196.Fx 6.0 .
197