On 24 October 2013 07:19, Mike <n...@none.com> wrote: > On Thursday, 24 October 2013 at 05:37:49 UTC, Walter Bright wrote: >> >> On 10/23/2013 5:43 PM, Mike wrote: >>> >>> I'm interested in ARM bare-metal programming with D, and I'm trying to >>> get my >>> head wrapped around how to approach this. I'm making progress, but I >>> found >>> something that was surprising to me: deprecation of the volatile keyword. >>> >>> In the bare-metal/hardware/driver world, this keyword is important to >>> ensure the >>> optimizer doesn't cache reads to memory-mapped IO, as some hardware >>> peripheral >>> may modify the value without involving the processor. >>> >>> I've read a few discussions on the D forums about the volatile keyword >>> debate, >>> but noone seemed to reconcile the need for volatile in memory-mapped IO. >>> Was >>> this an oversight? >>> >>> What's D's answer to this? If one were to use D to read from >>> memory-mapped IO, >>> how would one ensure the compiler doesn't cache the value? >> >> >> volatile was never a reliable method for dealing with memory mapped I/O. >> The correct and guaranteed way to make this work is to write two "peek" and >> "poke" functions to read/write a particular memory address: >> >> int peek(int* p); >> void poke(int* p, int value); >> >> Implement them in the obvious way, and compile them separately so the >> optimizer will not try to inline/optimize them. > > > Thanks for the answer, Walter. I think this would be acceptable in many > (most?) cases, but not where high performance is needed I think these > functions add too much overhead if they are not inlined and in a critical > path (bit-banging IO, for example). Afterall, a read/write to a volatile > address is a single atomic instruction, if done properly. >
Operations on volatile are *not* atomic. Nor do they establish a proper happens-before relationship for threading. This is why we have core.atomic as a portable synchronisation mechanism in D. Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';