volatile doesn't work as intended
Frederic Parain
frederic.parain at oracle.com
Thu Sep 26 13:56:30 UTC 2019
Hi Remi,
This is a known issue, the ‘volatile’ flag is currently ignored
for inline fields.
There’s no specification of the semantic of ‘volatile’ with respect
to inline classes yet, but the expectation most people will have
about it is to mean ‘atomic’ (which is not exactly how ‘volatile’
is specified in the JVMS).
Atomic access doesn’t necessarily means no flattening, and I would
be careful about making the promise that ‘volatile’ is a way to
control the layout of fields. We might end there, we might not.
Tobias and I discussed how to implement the atomic semantic.
Not flattening the field is the simplest solution.
But it is also possible to guarantee atomic accesses to flattened
field if they are small enough to be copied with an atomic instruction
from the HW and they are correctly aligned. However, according to
Tobias, the changes required in C2 to support this feature are not
simple: instead of handling each field of the inline field separately,
they have to be read or written with bulk operations, which impacts
the way C2 deals with and optimizes fields.
So, the first implementation of the ‘volatile’ semantic for inline fields
is going to use an indirection, but it is not guaranteed that it will
always produce an indirection in the future.
Unless this is a blocking issue for you, I have other field layout works
I’d like to complete before tackling this one.
Regards,
Fred
> On Sep 26, 2019, at 06:17, Remi Forax <forax at univ-mlv.fr> wrote:
>
> Hi guys,
> it seems that volatile doesn't work as it should with an inline value.
> a volatile field should force the field to be not flattened but the code below still throw an AssertionError
> (sometimes, you are to run the program several times).
>
> regards,
> Rémi
>
> public class ValueTearing {
> @__inline__
> static class Value {
> private int x;
> private int y;
>
> public Value(int x, int y) {
> this.x = x;
> this.y = y;
> }
> }
>
> public static void main(String[] args) {
> var box = new Object() { volatile Value shared; };
> var zero = new Value(0, 0);
> var one = new Value(1, 1);
> new Thread(() -> {
> for(;;) {
> box.shared = zero;
> }
> }).start();
> new Thread(() -> {
> for(;;) {
> box.shared = one;
> }
> }).start();
> for(;;) {
> var value = box.shared;
> if (value.x != value.y) {
> throw new AssertionError("oops " + value);
> }
> }
> }
> }
More information about the valhalla-dev
mailing list