tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: membar_enter semantics



> Date: Mon, 14 Feb 2022 02:01:13 +0000
> From: David Holland <dholland-tech%netbsd.org@localhost>
> 
> On Fri, Feb 11, 2022 at 01:33:04PM +0000, Taylor R Campbell wrote:
>  > membar_enter is currently documented to be a store-before-load/store
>  > barrier: https://man.netbsd.org/NetBSD-9.2/membar_ops.3
>  > 
>  >      membar_enter()
>  >            Any store preceding membar_enter() will happen before all memory
>  >            operations following it.
>  > 
>  > [...]
> 
> This problem (and others like it) are primarily caused by using silly
> names like "enter" and "exit" that don't mean anything. (That is: you
> could redefine enter to be any-before-any and exit to be
> read-before-read and it still wouldn't be obviously wrong to most
> people.)

The problem at hand is that one word in the documentation doesn't
reflect

- 15 years of implementation on x86, powerpc, and sparc,
- 15 years of usage, or
- sensible semantics for real-world use cases.

All the other NetBSD membars meet this -- as would the proposed
one-word documentation change.

> In general, things should be named by what they do, not by the
> context in which you're supposed to use them according to some
> cookbook thinking-averse approach.

Experience working in an environment where all possible membars are
available and named according to {load,store}-before-{load,store}
combinations tells me that it doesn't actually improve anything.

Instead, it just encourages people to overthink bad choices locally
without thinking about or documenting the two-sided _protocol_ between
threads, and then leave nonsensical barriers around because they
locally sounded good.

There's only two useful pairs in the real world:

- store-before-store and load-before-load
- load/store-before-store and load-before-load/store

Giving these pairs names that are paired words, like

- `exit' and `enter', or
- `producer' and `consumer', or
- `release' and `acquire',

is helpful because it means you can glance at code, and if you see
`exit' without a corresponding `enter' somewhere, that makes alarm
bells go off in your head.  You can review in the man page exactly
what the semantics of each pairing is -- and the man page has guidance
and usage examples to help.

In contrast, what is `store-before-load/store' supposed to pair with
in another thread?  Nobody knows!  It doesn't make any sense in any
real-world algorithms.

The names `acquire' and `release' are ubiquitous in the literature
today, so if we do any renaming those would be sensible to adopt (like
we did for atomic_load/store_*).  But that's a bigger change requiring
more effort that might be better spent just adopting the C11 API (but
keeping membar_producer/consumer because C11 doesn't have them).  For
the present, the documentation of our existing API should reflect the
useful and justifiable semantics as it is actually implemented and
used.

(I might be open to renaming membar_sync...  It should be called
membar_dekker -- a scary name so that nobody is ever inclined to reach
for it unless they actually know they're using Dekker's algorithm!  Or
maybe membar_full_dekker, with membar_dekker reserved for mere
store-before-load.  Right now the name is definitely too tempting for
its limited real-world utility, and doesn't set off enough alarm
bells.)


Home | Main Index | Thread Index | Old Index