- NetBSD Manual Pages
LOCALCOUNT(9) NetBSD Kernel Developer's Manual LOCALCOUNT(9)
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.
localcount, localcount_init, localcount_fini, localcount_acquire,
localcount_release, localcount_drain -- reference-count primitives
localcount_init(struct localcount *lc);
localcount_fini(struct localcount *lc);
localcount_acquire(struct localcount *lc);
localcount_release(struct localcount *lc, struct kcondvar *cv,
struct kmutex *mtx);
localcount_drain(struct localcount *lc, struct kcondvar *cv,
struct kmutex *mtx);
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
Dynamically initialize localcount lc for use.
No other operations can be performed on a localcount until it has
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-ini-
tialized by localcount_init().
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(); typ-
ically 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 cond-
var cv. The same cv and mtx must be used with
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(); removal
from the list would typically be protected by calling
pserialize_perform(9) to wait for any pserialize(9) readers to com-
Once the localcount object lc is passed to localcount_drain(), it
must be passed to localcount_fini() before any other re-use.
The core of the localcount implementation is located in
The header file sys/sys/localcount.h describes the public interface, and
interfaces that machine-dependent code must provide to support local-
atomic_ops(3), condvar(9), mutex(9), psref(9)
The localcount primitives first appeared in NetBSD 8.0.
localcount was designed by Taylor R. Campbell, who also provided a draft
implementation. The implementation was completed, tested, and integrated
by Paul Goyette.
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 opera-
tions are allowed until the localcount has been re-initialized.
NetBSD 9.2 February 25, 2019 NetBSD 9.2