[Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsHi,

K. Frank kfrank29.c at gmail.com
Tue Oct 23 22:14:11 CEST 2012


Hello Thomas (and Other Commenters)!

(Let me apologize for remaining a little off topic, as my question --
can volatiles be used for one thread to signal another thread to
stop -- is about c++ rather than Qt.)

On Mon, Oct 22, 2012 at 9:18 AM, Thomas McGuire <thomas.mcguire at kdab.com> wrote:
> Hi,
>
> On Monday 22 October 2012 14:16:33 Bo Thorsen wrote:
>> Den 22-10-2012 12:10, Jan Kundrát skrev:
>> > On 10/22/12 07:21, d3fault wrote:
>
>> > According to my understanding, the reason for this is the C++ memory
>> > model (or lack thereof); while volatile might look like a great way to
>> > force an "always load stuff from memory" approach, it does not impose a
>> > particular ordering of the read/write operations, so the
>> > compiler/CPU/memory controller/... are actually allowed to reorder
>> > access to other memory regions (and they really do that). That's not
>> > what you want to do.
>>
>> Not correct. Neither the compiler nor the CPU can reorder around a
>> volatile.
>
> volatile only forces the compiler to create an instruction to fetch the
> variable from memory again, to prevent caching in a register. The CPU doesn't
> even know about the volatile keyword anymore, it just sees a normal fetch
> instruction, and can therefore use the CPU cache.

If I understand the original purpose of volatile, to confirm, reading a
volatile should cause a true memory fetch, not just a fetch from
cache.  (As you mention below, if volatile is used for memory-mapped
IO, that IO won't actually occur if the fetch is just a cache fetch.)

> Therefore, if your two threads are living on different CPUs, one CPU might not
> see the update on the other CPU, since the CPU caches are not updated.
> volatile does not help with that, you need proper memory barriers.

Let's say that CPU A writes to the volatile and CPU B reads from
it.  Isn't it the case that A's write to the volatile must cause a true
memory store and not just a write to cache?  (Again, memory-mapped
IO would not work if the store is just a write to cache.)

Then when CPU B reads the volatile, mustn't it perform an actual
memory fetch, picking up the result of A's memory store?

>> The executed code has to write the true to the actual memory pointed to
>> by b and read it back from that in the if statement just after it.
>> Another thread could have changed it between the two statements. So no
>> register or cache can be used to speed this up and the compiler won't
>> optimize the check away.
>>
>> This does of course work. Otherwise, volatiles would be useless.
>
> It does not work in all cases, see above. volatile _is_ useless for threading,
> its orginal purpose was for memory-mapped IO.

Let me state for the record that I do not use volatiles for thread
synchronization.  But the issue at hand is not whether a volatile
can be used for full-featured thread synchronization, but whether
it can be used by one thread to signal a second looping thread
to quit.  It seems to me that volatile must cause the signalling
thread to perform an actual memory store and the thread to be
signalled to perform an actual memory fetch.  Yes, there is a
potential race condition in that the looping thread may read the
volatile after the signalling thread has written to it, but because
the thread is looping, it will come around and read the volatile
again, picking up the new value that signals it to quit.

Is there any plausible reading of the standard by which this
signalling mechanism could fail?  Do you know of any mainstream
platforms (hardware, os, and compiler) on which this signalling
mechanism does fail?

I can't conceive of any realistic scenario in which using volatiles
for memory-mapped IO (both the input and the output) would work
reliably, but nonetheless using volatiles for thread signalling would
not be equally reliable.

(The standard could perhaps say that the semantics of volatile are
formally and explicitly implementation defined, but I would then
argue that any reasonable implementation would have to define
volatile as a useless no-op, or that the thread signalling mechanism
will in fact work.)

> Regards,
> Thomas

Thanks for any further insight.


K. Frank



More information about the Interest mailing list