Inconsistent use of "volatile" when accessing shared memory?

From: Jeff Davis <pgsql(at)j-davis(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Inconsistent use of "volatile" when accessing shared memory?
Date: 2023-11-03 06:19:03
Message-ID: 784f72ac09061fe5eaa5335cc347340c367c73ac.camel@j-davis.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


I noticed that we occasionally use "volatile" to access shared memory,
but usually not; and I'm not clear on the rules for doing so. For
instance, AdvanceXLInsertBuffer() writes to XLogCtl->xlblocks[nextidx]
through a volatile pointer; but then immediately writes to XLogCtl-
>InitializedUpTo with a non-volatile pointer. There are also places in
procarray.c that make use of volatile through UINT32_ACCESS_ONCE(), and
of course there are atomics (which use volatile as well as guaranteeing
atomicity).

In theory, I think we're always supposed to access shared memory
through a volatile pointer, right? Otherwise a sufficiently smart (and
cruel) compiler could theoretically optimize away the load/store in
some surprising cases, or hold a value in a register longer than we
expect, and then any memory barriers would be useless.

But in practice we don't do that even for sensitive structures like the
one referenced by XLogCtl. My intuition up until now was that if we
access through a global pointer, then the compiler wouldn't completely
optimize away the store/load. I ran through some tests and that
assumption seems to hold up, at least in a few simple examples with gcc
at -O2, which seem to emit the loads/stores where expected.

What is the guidance here? Is the volatile pointer use in
AdvanceXLInsertBuffer() required, and if so, why not other places?

Regards,
Jeff Davis

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Richard Guo 2023-11-03 06:46:56 Re: Fix bogus Asserts in calc_non_nestloop_required_outer
Previous Message Richard Guo 2023-11-03 06:10:45 Re: Fix a wrong comment in setrefs.c