pcq(9): Document memory ordering guarantees.

This commit is contained in:
riastradh 2023-02-23 03:03:23 +00:00
parent d707e3dfbf
commit eecba6ae71
1 changed files with 58 additions and 1 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: pcq.9,v 1.8 2018/02/08 09:03:23 dholland Exp $ .\" $NetBSD: pcq.9,v 1.9 2023/02/23 03:03:23 riastradh Exp $
.\" .\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc. .\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -118,6 +118,63 @@ otherwise, return
The item must not have the value of The item must not have the value of
.Dv NULL . .Dv NULL .
.El .El
.Ss Memory ordering
Any memory operations sequenced before
.Fn pcq_put
of an item in one thread happen before all memory operations with data
dependencies on the item returned by
.Fn pcq_get
or
.Fn pcq_peek
in another thread.
For example:
.Bd -literal -offset indent
int mumble;
/* producer */
mumble = 42; // A
foo->x = 123; // B
refcnt = foo->refcnt; // C
pcq_put(pcq, foo);
KASSERT(refcnt == 0);
/* consumer */
foo = pcq_get(pcq);
if (foo == NULL)
return;
atomic_inc_uint(&foo->refcnt); // D
x = foo->x; // E
if (x == 123)
KASSERT(mumble == 42); // F
.Ed
.Pp
In this example, memory operations B and C happen-before D and E.
However, no ordering is guaranteed for A or F relative to any other
memory operations, because the memory location of
.Fa mumble
is independent of the pointer
.Fa foo
returned by
.Fn pcq_get .
.Pp
If you must guarantee A happens before F, then on the consumer side,
after
.Fn pcq_get
or
.Fn pcq_peek ,
you can call
.Fn membar_acquire
to turn it into an acquire operation instead of a consume operation;
.Fn pcq_put
serves as the matching release operation.
.Po
This is a little dicey.
Perhaps there should be separate
.Fn pcq_peek_acq
and
.Fn pcq_get_acq
operations if this semantics is necessary.
.Pc
.Sh CODE REFERENCES .Sh CODE REFERENCES
The The
.Nm .Nm