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 July 23, 2019 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 void 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_not_last "volatile u_int *count" 59.Sh DESCRIPTION 60The 61.Nm 62functions provide an API to manage a simple reference counter. 63The caller provides the storage for the counter in an unsigned integer. 64A pointer to this integer is passed via 65.Fa count . 66Usually the counter is used to manage the lifetime of an object and is 67stored as a member of the object. 68.Pp 69Currently all functions are implemented as static inline. 70.Pp 71The 72.Fn refcount_init 73function is used to set the initial value of the counter to 74.Fa value . 75It is normally used when creating a reference-counted object. 76.Pp 77The 78.Fn refcount_acquire 79function is used to acquire a new reference. 80The caller is responsible for ensuring that it holds a valid reference 81while obtaining a new reference. 82For example, 83if an object is stored on a list and the list holds a reference on the 84object, then holding a lock that protects the list provides sufficient 85protection for acquiring a new reference. 86.Pp 87The 88.Fn refcount_acquire_checked 89variant performs the same operation as 90.Fn refcount_acquire , 91but additionally checks that the 92.Fa count 93value does not overflow as result of the operation. 94It returns 95.Dv true 96if the reference was sucessfully obtained, and 97.Dv false 98if it was not, due to the overflow. 99.Pp 100The 101.Fn refcount_acquire_if_not_zero 102function is yet another variant of 103.Fn refcount_acquire , 104which only obtains the reference when some reference already exists. 105In other words, 106.Fa *count 107must be already greater than zero for the function to succeed, in which 108case the return value is 109.Dv true , 110otherwise 111.Dv false 112is returned. 113.Pp 114The 115.Fn refcount_release 116function is used to release an existing reference. 117The function returns true if the reference being released was 118the last reference; 119otherwise, it returns false. 120.Pp 121The 122.Fn refcount_release_if_not_last 123is a variant of 124.Fn refcount_release 125which only drops the reference when it is not the last reference. 126In other words, the function returns 127.Dv true 128when 129.Fa *count 130is greater than one, in which case 131.Fa *count is decremented. 132Otherwise, if 133.Fa *count 134is equal to one, the reference is not released and the function returns 135.Dv false . 136.Pp 137Note that these routines do not provide any inter-CPU synchronization or 138data protection for managing the counter. 139The caller is responsible for any additional synchronization needed by 140consumers of any containing objects. 141In addition, 142the caller is also responsible for managing the life cycle of any containing 143objects including explicitly releasing any resources when the last reference 144is released. 145.Pp 146The 147.Fn refcount_release 148unconditionally executes a release fence (see 149.Xr atomic 9 ) before releasing the reference, which 150synchronizes with an acquire fence executed right before 151returning the 152.Dv true 153value. 154This ensures that the destructor, supposedly executed by the caller after 155the last reference was dropped, sees all updates done during the lifetime 156of the object. 157.Sh RETURN VALUES 158The 159.Nm refcount_release 160function returns true when releasing the last reference and false when 161releasing any other reference. 162.Sh HISTORY 163These functions were introduced in 164.Fx 6.0 . 165