MEMBAR_OPS(3) | Library Functions Manual | MEMBAR_OPS(3)

# NAME

`membar_ops`, `membar_enter`, `membar_exit`, `membar_producer`, `membar_consumer`, `membar_datadep_consumer`, `membar_sync` —
memory access barrier operations

# SYNOPSIS

`#include <sys/atomic.h>`

void
`membar_enter`(void);

void
`membar_exit`(void);

void
`membar_producer`(void);

void
`membar_consumer`(void);

void
`membar_datadep_consumer`(void);

void
`membar_sync`(void);

# DESCRIPTION

The `membar_ops` family of functions provide memory access barrier operations necessary for synchronization in multiprocessor execution environments that have relaxed load and store order.

`membar_enter`()
  Any store preceding `membar_enter`() will reach global visibility before all loads and stores following it.

  `membar_enter`() is typically used in code that implements locking primitives to ensure that a lock protects its data.

`membar_exit`()
  All loads and stores preceding `membar_exit`() will reach global visibility before any store that follows it.

  `membar_exit`() is typically used in code that implements locking primitives to ensure that a lock protects its data.

`membar_producer`()
  All stores preceding the memory barrier will reach global visibility before any stores after the memory barrier reach global visibility.
`membar_consumer`()
  All loads preceding the memory barrier will complete before any loads after the memory barrier complete.
`membar_datadep_consumer`()
  Same as `membar_consumer`(), but limited to loads of addresses dependent on prior loads, or ‘data-dependent’ loads:

      int **pp, *p, v;

      p = *pp;
      membar_datadep_consumer();
      v = *p;
      consume(v);

  Does not guarantee ordering of loads in branches, or ‘control-dependent’ loads -- you must use `membar_consumer`() instead:

      int *ok, *p, v;

      if (*ok) {
      	membar_consumer();
      	v = *p;
      	consume(v);
      }

  Most CPUs do not reorder data-dependent loads (i.e., most CPUs guarantee that cached values are not stale in that case), so `membar_datadep_consumer`() is a no-op on those CPUs.

`membar_sync`()
  All loads and stores preceding the memory barrier will complete and reach global visibility before any loads and stores after the memory barrier complete and reach global visibility.

# SEE ALSO

atomic_ops(3)

# HISTORY

The `membar_ops` functions first appeared in NetBSD 5.0. The data-dependent load barrier, `membar_datadep_consumer`(), first appeared in NetBSD 7.0.

November 20, 2014 | NetBSD 9.0