LOCALCOUNT(9) | Kernel Developer's Manual | LOCALCOUNT(9)

# 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.

  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 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 complete.

  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.

February 25, 2019 | NetBSD 9.3