NAME
localcount
,
localcount_init
,
localcount_fini
,
localcount_acquire
,
localcount_release
,
localcount_drain
—
reference-count primitives
SYNOPSIS
#include
<sys/localcount.h>
void
localcount_init
(struct
localcount *lc);
void
localcount_fini
(struct
localcount *lc);
void
localcount_acquire
(struct
localcount *lc);
void
localcount_release
(struct
localcount *lc, struct
kcondvar *cv, struct
kmutex *mtx);
void
localcount_drain
(struct
localcount *lc, struct
kcondvar *cv, struct
kmutex *mtx);
DESCRIPTION
Localcounts are used in the kernel to implement a medium-weight
reference counting mechanism. During normal operations, localcounts do not
need the interprocessor synchronization associated with
atomic_ops(3) atomic memory operations, and (unlike
psref(9)) localcount
references can be held
across sleeps and can migrate between CPUs. Draining a
localcount
requires more expensive interprocessor
synchronization than
atomic_ops(3) (similar to
psref(9)). And localcount
references require
eight bytes of memory per object per-CPU, significantly more than
atomic_ops(3) and almost always more than
psref(9).
As a rough heuristic, localcount
should be
used for classes of objects of which there are perhaps a few dozen instances
(such as autoconf(9) devices) but not thousands of instances (such as
network flows) and on which there may be a mixture of long-term I/O waits,
such as xyzread for a device xyz(4), and short-term fast operations, such as
xyzioctl(IOC_READ_A_CPU_REG)
.
FUNCTIONS
localcount_init
(lc)- Dynamically initialize localcount lc for use.
No other operations can be performed on a localcount until it has been initialized.
localcount_fini
(lc)- Release resources used by localcount lc. The caller
must have already called
localcount_drain
(). The localcount may not be used afterlocalcount_fini
() has been called until it has been re-initialized bylocalcount_init
(). localcount_acquire
(lc)- Acquire a reference to the localcount lc.
The caller must ensure by some other mechanism that the localcount will not be destroyed before the call to
localcount_acquire
(); typically this will be via a pserialize(9) read section. localcount_release
(lc, cv, mtx)- Release a reference to the localcount lc. If the
localcount is currently being drained, the mutex mtx
will be used to synchronize updates to the global reference count (i.e.,
the total across all CPUs). If the reference count goes to zero,
localcount_release
() will broadcast availability of the condvar cv. localcount_drain
(lc, cv, mtx)- Wait for all references to the localcount lc to be
released. The caller must hold the mutex mtx; the
mutex will be released during inter-CPU cross-calls (see
xcall(9)) and while waiting on the condvar
cv. The same cv and
mtx must be used with
localcount_release
().The caller must guarantee that no new references can be acquired with
localcount_acquire
() before callinglocalcount_drain
(). For example, any object that may be found in a list and acquired must be removed from the list before callinglocalcount_drain
(); removal from the list would typically be protected by calling pserialize_perform(9) to wait for any pserialize(9) readers to complete.Once the localcount object lc is passed to
localcount_drain
(), it must be passed tolocalcount_fini
() before any other re-use.
CODE REFERENCES
The core of the localcount implementation is located in sys/kern/subr_localcount.c.
The header file sys/sys/localcount.h describes the public interface, and interfaces that machine-dependent code must provide to support localcounts.
SEE ALSO
HISTORY
The localcount primitives first appeared in NetBSD 8.0.
AUTHORS
localcount
was designed by
Taylor R. Campbell, who also provided a draft
implementation. The implementation was completed, tested, and integrated by
Paul Goyette.
CAVEATS
The localcount
facility does not provide
any way to examine the reference count without actually waiting for the
count to reach zero.
Waiting for a localcount
reference count
to drain (reach zero) is a one-shot operation. Once the
localcount
has been drained, no further operations
are allowed until the localcount
has been
re-initialized.