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.\" 6*43806bc5SKonstantin Belousov.\" Copyright (c) 2019 The FreeBSD Foundation, Inc. 7*43806bc5SKonstantin Belousov.\" 8*43806bc5SKonstantin Belousov.\" Parts of this documentation was written by 9*43806bc5SKonstantin Belousov.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship 10*43806bc5SKonstantin Belousov.\" from the FreeBSD Foundation. 11*43806bc5SKonstantin 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*43806bc5SKonstantin Belousov.Dd July 23, 2019 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" 49497435aaSJohn Baldwin.Ft void 50497435aaSJohn Baldwin.Fn refcount_acquire "volatile u_int *count" 5113ff4eb1SKonstantin Belousov.Ft bool 52*43806bc5SKonstantin Belousov.Fn refcount_acquire_checked "volatile u_int *count" 53*43806bc5SKonstantin Belousov.Ft bool 54*43806bc5SKonstantin Belousov.Fn refcount_acquire_if_not_zero "volatile u_int *count" 55*43806bc5SKonstantin Belousov.Ft bool 56497435aaSJohn Baldwin.Fn refcount_release "volatile u_int *count" 57*43806bc5SKonstantin Belousov.Ft bool 58*43806bc5SKonstantin Belousov.Fn refcount_release_if_not_last "volatile u_int *count" 59497435aaSJohn Baldwin.Sh DESCRIPTION 60497435aaSJohn BaldwinThe 61497435aaSJohn Baldwin.Nm 62497435aaSJohn Baldwinfunctions provide an API to manage a simple reference counter. 63497435aaSJohn BaldwinThe caller provides the storage for the counter in an unsigned integer. 64497435aaSJohn BaldwinA pointer to this integer is passed via 65497435aaSJohn Baldwin.Fa count . 66497435aaSJohn BaldwinUsually the counter is used to manage the lifetime of an object and is 67497435aaSJohn Baldwinstored as a member of the object. 68497435aaSJohn Baldwin.Pp 69*43806bc5SKonstantin BelousovCurrently all functions are implemented as static inline. 70*43806bc5SKonstantin Belousov.Pp 71497435aaSJohn BaldwinThe 72497435aaSJohn Baldwin.Fn refcount_init 73497435aaSJohn Baldwinfunction is used to set the initial value of the counter to 74497435aaSJohn Baldwin.Fa value . 75497435aaSJohn BaldwinIt is normally used when creating a reference-counted object. 76497435aaSJohn Baldwin.Pp 77497435aaSJohn BaldwinThe 78497435aaSJohn Baldwin.Fn refcount_acquire 79497435aaSJohn Baldwinfunction is used to acquire a new reference. 80497435aaSJohn BaldwinThe caller is responsible for ensuring that it holds a valid reference 81497435aaSJohn Baldwinwhile obtaining a new reference. 82497435aaSJohn BaldwinFor example, 83497435aaSJohn Baldwinif an object is stored on a list and the list holds a reference on the 84497435aaSJohn Baldwinobject, then holding a lock that protects the list provides sufficient 85497435aaSJohn Baldwinprotection for acquiring a new reference. 86497435aaSJohn Baldwin.Pp 87497435aaSJohn BaldwinThe 88*43806bc5SKonstantin Belousov.Fn refcount_acquire_checked 89*43806bc5SKonstantin Belousovvariant performs the same operation as 90*43806bc5SKonstantin Belousov.Fn refcount_acquire , 91*43806bc5SKonstantin Belousovbut additionally checks that the 92*43806bc5SKonstantin Belousov.Fa count 93*43806bc5SKonstantin Belousovvalue does not overflow as result of the operation. 94*43806bc5SKonstantin BelousovIt returns 95*43806bc5SKonstantin Belousov.Dv true 96*43806bc5SKonstantin Belousovif the reference was sucessfully obtained, and 97*43806bc5SKonstantin Belousov.Dv false 98*43806bc5SKonstantin Belousovif it was not, due to the overflow. 99*43806bc5SKonstantin Belousov.Pp 100*43806bc5SKonstantin BelousovThe 101*43806bc5SKonstantin Belousov.Fn refcount_acquire_if_not_zero 102*43806bc5SKonstantin Belousovfunction is yet another variant of 103*43806bc5SKonstantin Belousov.Fn refcount_acquire , 104*43806bc5SKonstantin Belousovwhich only obtains the reference when some reference already exists. 105*43806bc5SKonstantin BelousovIn other words, 106*43806bc5SKonstantin Belousov.Fa *count 107*43806bc5SKonstantin Belousovmust be already greater than zero for the function to succeed, in which 108*43806bc5SKonstantin Belousovcase the return value is 109*43806bc5SKonstantin Belousov.Dv true , 110*43806bc5SKonstantin Belousovotherwise 111*43806bc5SKonstantin Belousov.Dv false 112*43806bc5SKonstantin Belousovis returned. 113*43806bc5SKonstantin Belousov.Pp 114*43806bc5SKonstantin BelousovThe 115497435aaSJohn Baldwin.Fn refcount_release 116497435aaSJohn Baldwinfunction is used to release an existing reference. 11713ff4eb1SKonstantin BelousovThe function returns true if the reference being released was 118497435aaSJohn Baldwinthe last reference; 11913ff4eb1SKonstantin Belousovotherwise, it returns false. 120497435aaSJohn Baldwin.Pp 121*43806bc5SKonstantin BelousovThe 122*43806bc5SKonstantin Belousov.Fn refcount_release_if_not_last 123*43806bc5SKonstantin Belousovis a variant of 124*43806bc5SKonstantin Belousov.Fn refcount_release 125*43806bc5SKonstantin Belousovwhich only drops the reference when it is not the last reference. 126*43806bc5SKonstantin BelousovIn other words, the function returns 127*43806bc5SKonstantin Belousov.Dv true 128*43806bc5SKonstantin Belousovwhen 129*43806bc5SKonstantin Belousov.Fa *count 130*43806bc5SKonstantin Belousovis greater than one, in which case 131*43806bc5SKonstantin Belousov.Fa *count is decremented. 132*43806bc5SKonstantin BelousovOtherwise, if 133*43806bc5SKonstantin Belousov.Fa *count 134*43806bc5SKonstantin Belousovis equal to one, the reference is not released and the function returns 135*43806bc5SKonstantin Belousov.Dv false . 136*43806bc5SKonstantin Belousov.Pp 137*43806bc5SKonstantin BelousovNote that these routines do not provide any inter-CPU synchronization or 138*43806bc5SKonstantin Belousovdata protection for managing the counter. 139497435aaSJohn BaldwinThe caller is responsible for any additional synchronization needed by 140497435aaSJohn Baldwinconsumers of any containing objects. 141497435aaSJohn BaldwinIn addition, 142497435aaSJohn Baldwinthe caller is also responsible for managing the life cycle of any containing 143497435aaSJohn Baldwinobjects including explicitly releasing any resources when the last reference 144497435aaSJohn Baldwinis released. 145*43806bc5SKonstantin Belousov.Pp 146*43806bc5SKonstantin BelousovThe 147*43806bc5SKonstantin Belousov.Fn refcount_release 148*43806bc5SKonstantin Belousovunconditionally executes a release fence (see 149*43806bc5SKonstantin Belousov.Xr atomic 9 ) before releasing the reference, which 150*43806bc5SKonstantin Belousovsynchronizes with an acquire fence executed right before 151*43806bc5SKonstantin Belousovreturning the 152*43806bc5SKonstantin Belousov.Dv true 153*43806bc5SKonstantin Belousovvalue. 154*43806bc5SKonstantin BelousovThis ensures that the destructor, supposedly executed by the caller after 155*43806bc5SKonstantin Belousovthe last reference was dropped, sees all updates done during the lifetime 156*43806bc5SKonstantin Belousovof the object. 157497435aaSJohn Baldwin.Sh RETURN VALUES 158497435aaSJohn BaldwinThe 159497435aaSJohn Baldwin.Nm refcount_release 16013ff4eb1SKonstantin Belousovfunction returns true when releasing the last reference and false when 161497435aaSJohn Baldwinreleasing any other reference. 162497435aaSJohn Baldwin.Sh HISTORY 163497435aaSJohn BaldwinThese functions were introduced in 164497435aaSJohn Baldwin.Fx 6.0 . 165