DIP62: Volatile type qualifier for unoptimizable variables in embedded programming

Johannes Pfau via Digitalmars-d digitalmars-d at puremagic.com
Tue Jul 15 13:43:17 PDT 2014


Am Tue, 15 Jul 2014 12:48:21 -0700
schrieb Walter Bright <newshound2 at digitalmars.com>:

> On 7/15/2014 9:25 AM, Johannes Pfau wrote:
> > DIP62 describes how to solve this problem and make embedded
> > programming a first-class citizen in D:
> > http://wiki.dlang.org/DIP62
> 
> This is a particularly well-written DIP, thank you and the other
> contributors to it.
> 
> 
> > * Although it's explained in the DIP in detail, I must mention this
> >    here again: We need _first-class_ support for embedded
> > programming in D. Workarounds might be available (peek/poke, inline
> > asm) but it will be obvious to most C programmers that C has got
> > the better solution with the volatile qualifier. D enthusiasts
> > might be happy if they can use workarounds to make D work on
> > microcontrollers. But if we want to appeal to outsiders we can't
> > confront them with obvious workarounds and hacks as the first thing
> > they see in D. And if they think embedded programming is a second
> > class citizen in D, why should they use it at all?
> 
> 1. Volatile has caused a major increase in the complexity of the C++
> type system 
> - a complexity far out of proportion to the value it provides. It
> would have a similar complex and pervasive effect on the D type
> system.

Well as described in the DIP it works just like shared from an
implementation point of view, so I doesn't add much complexity in the
compiler / type system.

> 
> 2. You mention peek/poke here, but not in the DIP. [Background: I've
> designed and built embedded systems, and written the software for
> them.] There aren't that many memory-mapped I/O registers. They just
> aren't worth bending the entire language around them. Peek/poke work
> just fine:

Indeed there's nothing about peek/poke in DIP62, I thought I added that.
The main point is that we can not leak pointers to volatile memory to
users and pretend it's normal memory. This will lead to many problems:
-------------------------------------------------------------
//In runtime:
enum int* SOME_REG = 0xFFFF;

//In user code
peek(SOME_REG);
poke(SOME_REG);
*SOME_REG = 1; //Oops, forgot poke! This is not acceptable
-------------------------------------------------------------
This is like saying we don't need the shared qualifier as people
should use atomicOp to access the data.

This is actually the crucial point about this DIP. If we can make this
work without a type qualifier than that's fine as well.


The only other solution to this is a wrapper as described by Artur
Skawina. (Can basically wrap around peek/poke):
http://dpaste.dzfl.pl/6f8ca6d7e7b8

But the problem there is that it produces quite some overhead right
now. We'd need to enforce at least these points:
* @property value must be inlined, there should not be a 'normal'
  function at all
* value must always be treated as in release mode. For example DMD adds
  an assert(this) into that function which is not acceptable
* There should be no TypeInfo for Volatile!T
* There should be no initializer data for Volatile!T
* WE should be careful with debug info for Volatile!T
* We should not emit postblits or similar stuff

In the end the struct basically has to 'vanish' from the object file
and '@property value' needs to be substituted into the correct places. 

> 
> 1. they can be implemented as compiler intrinsics so there is no
> efficiency cost for using them
> 
> 2. they make it clear in user code when memory-mapped I/O is accessed

Way more dangerous and important is if you forget peek/poke.

> 
> 3. if you really hate peek/poke calls appearing in the code, you can
> use UFCS to make them look like variables

But you cant do REGISTER.peek() |= 0b1;

> 
> 4. they are simple to explain and understand, they do not introduce a
> numbing complexity to the type system
> 

Sorry, but I don't buy any of these complexity arguments. A few months
ago you suggested namespaces for D - in addition to modules - which
would have lead to a complexity disaster.
This just shows the priorities of the project leads:
Desktop apps matter, we add @nogc, c++ namespaces, shared, immutable,
const, -cov, ...
but for embedded systems we won't even add one qualifier.

> 5. peek/poke will not add to the confusion about the difference
> between volatile and shared. No sane person would be tempted to use
> peek/poke to implement concurrency. The semantics of volatile in
> other languages won't confuse things for D peek/poke.

actually peek/poke are not that different from atomicOp from a
syntax perspective ;-) You'll still have to educate people about the
difference.

> 
> The one thing peek/poke doesn't offer is transitivity. C/C++ don't
> offer volatile transitivity either. I'm not at all sure that anyone
> builds a data structure in memory-mapped registers, so I'm not
> convinced this is a need.

Well such data structures are sometimes used in interrupts, but not that
often.


More information about the Digitalmars-d mailing list