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 after
localcount_fini() has been called until it has been
re-initialized by localcount_init().
-
-
- localcount_acquire(lc)
- Acquire a reference to the localcount
lc.
-
-
- 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 calling
localcount_drain(). For example, any object that may be
found in a list and acquired must be removed from the list before calling
localcount_drain(). Once the localcount object
lc is passed to
localcount_drain(), it must be passed to
localcount_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
atomic_ops(3),
condvar(9),
mutex(9),
psref(9)
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.