pcq(9): Document memory ordering guarantees.
This commit is contained in:
parent
d707e3dfbf
commit
eecba6ae71
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue