ARM bare-metal programming in D (cont) - volatile

John Colvin john.loughran.colvin at gmail.com
Thu Oct 24 02:27:18 PDT 2013


On Thursday, 24 October 2013 at 08:20:43 UTC, Iain Buclaw wrote:
> On 24 October 2013 08:18, Mike <none at none.com> wrote:
>> On Thursday, 24 October 2013 at 06:37:08 UTC, Iain Buclaw 
>> wrote:
>>>
>>> On 24 October 2013 06:37, Walter Bright 
>>> <newshound2 at digitalmars.com>
>>> 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.
>>>
>>>
>>> Are you talking dmd or in general (it's hard to tell).  In 
>>> gdc,
>>> volatile is the same as in gcc/g++ in behaviour.  Although in 
>>> one
>>> aspect, when the default storage model was switched to 
>>> thread-local,
>>> that made volatile on it's own pointless.
>>>
>>> As a side note, 'shared' is considered a volatile type in 
>>> gdc, which
>>> differs from the deprecated keyword which set volatile at a
>>> decl/expression level.  There is a difference in semantics, 
>>> but it
>>> escapes this author at 6.30am in the morning.  :o)
>>>
>>> In any case, using shared would be my recommended route for 
>>> you to go
>>> down.
>>>
>>>
>>>> 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.
>>>
>>>
>>> +1.  Using an optimiser along with code that talks to 
>>> hardware can
>>> result in bizarre behaviour.
>>
>>
>> Well, I've done some reading about "shared" but I don't quite 
>> grasp it yet.
>> I still have some learning to do.  That's my problem, but if 
>> you feel like
>> explaining how it can be used in place of volatile for 
>> hardware register
>> access, that would be awfully nice.
>
> 'shared' guarantees that all reads and writes specified in 
> source code
> happen in the exact order specified with no omissions, as there 
> may be
> other threads reading/writing to the variable at the same time.
>
>
> Regards

Is it actually implemented as such in any D compiler? That's a 
lot of memory barriers, shared would have to come with a massive 
SLOW! notice on it. Not saying that's a bad choice necessarily, 
but I was pretty sure this had never been implemented.


More information about the Digitalmars-d mailing list