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