1497435aaSJohn Baldwin.\" 2179fa75eSJohn Baldwin.\" Copyright (c) 2009 Hudson River Trading LLC 3497435aaSJohn Baldwin.\" Written by: John H. Baldwin <jhb@FreeBSD.org> 4497435aaSJohn Baldwin.\" All rights reserved. 5497435aaSJohn Baldwin.\" 643806bc5SKonstantin Belousov.\" Copyright (c) 2019 The FreeBSD Foundation, Inc. 743806bc5SKonstantin Belousov.\" 843806bc5SKonstantin Belousov.\" Parts of this documentation was written by 943806bc5SKonstantin Belousov.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship 1043806bc5SKonstantin Belousov.\" from the FreeBSD Foundation. 1143806bc5SKonstantin Belousov.\" 12497435aaSJohn Baldwin.\" Redistribution and use in source and binary forms, with or without 13497435aaSJohn Baldwin.\" modification, are permitted provided that the following conditions 14497435aaSJohn Baldwin.\" are met: 15497435aaSJohn Baldwin.\" 1. Redistributions of source code must retain the above copyright 16497435aaSJohn Baldwin.\" notice, this list of conditions and the following disclaimer. 17497435aaSJohn Baldwin.\" 2. Redistributions in binary form must reproduce the above copyright 18497435aaSJohn Baldwin.\" notice, this list of conditions and the following disclaimer in the 19497435aaSJohn Baldwin.\" documentation and/or other materials provided with the distribution. 20497435aaSJohn Baldwin.\" 21497435aaSJohn Baldwin.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22497435aaSJohn Baldwin.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23497435aaSJohn Baldwin.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24497435aaSJohn Baldwin.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25497435aaSJohn Baldwin.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26497435aaSJohn Baldwin.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27497435aaSJohn Baldwin.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28497435aaSJohn Baldwin.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29497435aaSJohn Baldwin.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30497435aaSJohn Baldwin.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31497435aaSJohn Baldwin.\" SUCH DAMAGE. 32497435aaSJohn Baldwin.\" 33497435aaSJohn Baldwin.\" $FreeBSD$ 34497435aaSJohn Baldwin.\" 35*e8900461SMark Johnston.Dd November 2, 2020 36497435aaSJohn Baldwin.Dt REFCOUNT 9 37497435aaSJohn Baldwin.Os 38497435aaSJohn Baldwin.Sh NAME 39497435aaSJohn Baldwin.Nm refcount , 40497435aaSJohn Baldwin.Nm refcount_init , 41497435aaSJohn Baldwin.Nm refcount_acquire , 42497435aaSJohn Baldwin.Nm refcount_release 43497435aaSJohn Baldwin.Nd manage a simple reference counter 44497435aaSJohn Baldwin.Sh SYNOPSIS 45497435aaSJohn Baldwin.In sys/param.h 46497435aaSJohn Baldwin.In sys/refcount.h 47497435aaSJohn Baldwin.Ft void 481e9469d1SChristian Brueffer.Fn refcount_init "volatile u_int *count" "u_int value" 49*e8900461SMark Johnston.Ft u_int 50*e8900461SMark Johnston.Fn refcount_load "volatile u_int *count" 51497435aaSJohn Baldwin.Ft void 52497435aaSJohn Baldwin.Fn refcount_acquire "volatile u_int *count" 5313ff4eb1SKonstantin Belousov.Ft bool 5443806bc5SKonstantin Belousov.Fn refcount_acquire_checked "volatile u_int *count" 5543806bc5SKonstantin Belousov.Ft bool 5643806bc5SKonstantin Belousov.Fn refcount_acquire_if_not_zero "volatile u_int *count" 5743806bc5SKonstantin Belousov.Ft bool 58497435aaSJohn Baldwin.Fn refcount_release "volatile u_int *count" 5943806bc5SKonstantin Belousov.Ft bool 60*e8900461SMark Johnston.Fn refcount_release_if_last "volatile u_int *count" 61*e8900461SMark Johnston.Ft bool 6243806bc5SKonstantin Belousov.Fn refcount_release_if_not_last "volatile u_int *count" 63497435aaSJohn Baldwin.Sh DESCRIPTION 64497435aaSJohn BaldwinThe 65497435aaSJohn Baldwin.Nm 66497435aaSJohn Baldwinfunctions provide an API to manage a simple reference counter. 67497435aaSJohn BaldwinThe caller provides the storage for the counter in an unsigned integer. 68497435aaSJohn BaldwinA pointer to this integer is passed via 69497435aaSJohn Baldwin.Fa count . 70497435aaSJohn BaldwinUsually the counter is used to manage the lifetime of an object and is 71497435aaSJohn Baldwinstored as a member of the object. 72497435aaSJohn Baldwin.Pp 7343806bc5SKonstantin BelousovCurrently all functions are implemented as static inline. 7443806bc5SKonstantin Belousov.Pp 75497435aaSJohn BaldwinThe 76497435aaSJohn Baldwin.Fn refcount_init 77497435aaSJohn Baldwinfunction is used to set the initial value of the counter to 78497435aaSJohn Baldwin.Fa value . 79497435aaSJohn BaldwinIt is normally used when creating a reference-counted object. 80497435aaSJohn Baldwin.Pp 81497435aaSJohn BaldwinThe 82*e8900461SMark Johnston.Fn refcount_load 83*e8900461SMark Johnstonfunction returns a snapshot of the counter value. 84*e8900461SMark JohnstonThis value may immediately become out-of-date in the absence of external 85*e8900461SMark Johnstonsynchronization. 86*e8900461SMark Johnston.Fn refcount_load 87*e8900461SMark Johnstonshould be used instead of relying on the properties of the 88*e8900461SMark Johnston.Vt volatile 89*e8900461SMark Johnstonqualifier. 90*e8900461SMark Johnston.Pp 91*e8900461SMark JohnstonThe 92497435aaSJohn Baldwin.Fn refcount_acquire 93497435aaSJohn Baldwinfunction is used to acquire a new reference. 94497435aaSJohn BaldwinThe caller is responsible for ensuring that it holds a valid reference 95497435aaSJohn Baldwinwhile obtaining a new reference. 96497435aaSJohn BaldwinFor example, 97497435aaSJohn Baldwinif an object is stored on a list and the list holds a reference on the 98497435aaSJohn Baldwinobject, then holding a lock that protects the list provides sufficient 99497435aaSJohn Baldwinprotection for acquiring a new reference. 100497435aaSJohn Baldwin.Pp 101497435aaSJohn BaldwinThe 10243806bc5SKonstantin Belousov.Fn refcount_acquire_checked 10343806bc5SKonstantin Belousovvariant performs the same operation as 10443806bc5SKonstantin Belousov.Fn refcount_acquire , 10543806bc5SKonstantin Belousovbut additionally checks that the 10643806bc5SKonstantin Belousov.Fa count 10743806bc5SKonstantin Belousovvalue does not overflow as result of the operation. 10843806bc5SKonstantin BelousovIt returns 10943806bc5SKonstantin Belousov.Dv true 11043806bc5SKonstantin Belousovif the reference was sucessfully obtained, and 11143806bc5SKonstantin Belousov.Dv false 11243806bc5SKonstantin Belousovif it was not, due to the overflow. 11343806bc5SKonstantin Belousov.Pp 11443806bc5SKonstantin BelousovThe 11543806bc5SKonstantin Belousov.Fn refcount_acquire_if_not_zero 11643806bc5SKonstantin Belousovfunction is yet another variant of 11743806bc5SKonstantin Belousov.Fn refcount_acquire , 11843806bc5SKonstantin Belousovwhich only obtains the reference when some reference already exists. 11943806bc5SKonstantin BelousovIn other words, 12043806bc5SKonstantin Belousov.Fa *count 12143806bc5SKonstantin Belousovmust be already greater than zero for the function to succeed, in which 12243806bc5SKonstantin Belousovcase the return value is 12343806bc5SKonstantin Belousov.Dv true , 12443806bc5SKonstantin Belousovotherwise 12543806bc5SKonstantin Belousov.Dv false 12643806bc5SKonstantin Belousovis returned. 12743806bc5SKonstantin Belousov.Pp 12843806bc5SKonstantin BelousovThe 129497435aaSJohn Baldwin.Fn refcount_release 130497435aaSJohn Baldwinfunction is used to release an existing reference. 13113ff4eb1SKonstantin BelousovThe function returns true if the reference being released was 132497435aaSJohn Baldwinthe last reference; 13313ff4eb1SKonstantin Belousovotherwise, it returns false. 134497435aaSJohn Baldwin.Pp 13543806bc5SKonstantin BelousovThe 136*e8900461SMark Johnston.Fn refcount_release_if_last 137*e8900461SMark Johnstonand 13843806bc5SKonstantin Belousov.Fn refcount_release_if_not_last 139*e8900461SMark Johnstonfunctions are variants of 14043806bc5SKonstantin Belousov.Fn refcount_release 141*e8900461SMark Johnstonwhich only drop the reference when it is or is not the last reference, 142*e8900461SMark Johnstonrespectively. 143*e8900461SMark JohnstonIn other words, 144*e8900461SMark Johnston.Fn refcount_release_if_last 145*e8900461SMark Johnstonreturns 146*e8900461SMark Johnston.Dv true 147*e8900461SMark Johnstonwhen 148*e8900461SMark Johnston.Fa *count 149*e8900461SMark Johnstonis equal to one, in which case it is decremented to zero. 150*e8900461SMark JohnstonOtherwise, 151*e8900461SMark Johnston.Fa *count 152*e8900461SMark Johnstonis not modified and the function returns 153*e8900461SMark Johnston.Dv false . 154*e8900461SMark JohnstonSimilarly, 155*e8900461SMark Johnston.Fn refcount_release_if_not_last 156*e8900461SMark Johnstonreturns 15743806bc5SKonstantin Belousov.Dv true 15843806bc5SKonstantin Belousovwhen 15943806bc5SKonstantin Belousov.Fa *count 16043806bc5SKonstantin Belousovis greater than one, in which case 161*e8900461SMark Johnston.Fa *count 162*e8900461SMark Johnstonis decremented. 16343806bc5SKonstantin BelousovOtherwise, if 16443806bc5SKonstantin Belousov.Fa *count 16543806bc5SKonstantin Belousovis equal to one, the reference is not released and the function returns 16643806bc5SKonstantin Belousov.Dv false . 16743806bc5SKonstantin Belousov.Pp 16843806bc5SKonstantin BelousovNote that these routines do not provide any inter-CPU synchronization or 16943806bc5SKonstantin Belousovdata protection for managing the counter. 170497435aaSJohn BaldwinThe caller is responsible for any additional synchronization needed by 171497435aaSJohn Baldwinconsumers of any containing objects. 172497435aaSJohn BaldwinIn addition, 173497435aaSJohn Baldwinthe caller is also responsible for managing the life cycle of any containing 174497435aaSJohn Baldwinobjects including explicitly releasing any resources when the last reference 175497435aaSJohn Baldwinis released. 17643806bc5SKonstantin Belousov.Pp 17743806bc5SKonstantin BelousovThe 17843806bc5SKonstantin Belousov.Fn refcount_release 17943806bc5SKonstantin Belousovunconditionally executes a release fence (see 18043806bc5SKonstantin Belousov.Xr atomic 9 ) before releasing the reference, which 18143806bc5SKonstantin Belousovsynchronizes with an acquire fence executed right before 18243806bc5SKonstantin Belousovreturning the 18343806bc5SKonstantin Belousov.Dv true 18443806bc5SKonstantin Belousovvalue. 18543806bc5SKonstantin BelousovThis ensures that the destructor, supposedly executed by the caller after 18643806bc5SKonstantin Belousovthe last reference was dropped, sees all updates done during the lifetime 18743806bc5SKonstantin Belousovof the object. 188497435aaSJohn Baldwin.Sh RETURN VALUES 189497435aaSJohn BaldwinThe 190497435aaSJohn Baldwin.Nm refcount_release 19113ff4eb1SKonstantin Belousovfunction returns true when releasing the last reference and false when 192497435aaSJohn Baldwinreleasing any other reference. 193497435aaSJohn Baldwin.Sh HISTORY 194497435aaSJohn BaldwinThese functions were introduced in 195497435aaSJohn Baldwin.Fx 6.0 . 196