On Thu, Aug 23, 2012 at 1:18 AM, David Brown <david.br...@hesbynett.no> wrote:
> (I've put this back on the mailing list - I assume you meant to do that, and
> just pressed the wrong "reply" button.)

Oops.

> I can see your point, but I am not convinced it is correct.  You are talking
> about a very grey area of the C specs here - "volatile" is simply not well
> enough specified in the C standards.  There was a well-publicised paper
> recently which looked at code generated by a variety of compilers for
> different volatile constructs, which concluded that most (or all, I think)
> compilers got things wrong in some circumstances.  The obvious conclusion to
> take from that is that you must keep volatile code simple.  If not, then
> either /you/ will get it wrong, or the /compiler/ will get it wrong.  And
> even if both are right, the hardware can still be a limitation.  This very
> example shows the problems caused by complex volatile code - you agree the
> compiler's output is correct based on the source code, yet it does not do
> what you want it to do or think it should do.
>
> So by the coding rules I use, the code you wrote is wrong - regardless of
> what the compiler generates, or even whether or not it works.

Ah, that makes sense. In other words, proceed with caution - here be
dragons. You rules basically describe the "safe" ways to use volatile
variables, and anything else might mean trouble.

> Then separate the two operations into two lines of code:
>
> uint8_t newBits = (state >> 1) & DIRTY_FLAG;
> state |= newBits;
>
> That makes the code much clearer - and it explicitly shows that the two
> operations can be split up.  Otherwise you've got a maintenance problem for
> the future when a new programmer tries to figure out what works or does not
> work.
>
> And maybe you'll be lucky and the "|=" will be implemented atomically with
> that code.  Simple statements are critical to getting volatile right, and it
> gives the compiler the best chance.  There are no guarantees, however.

I tried this, and the emitted code stays the same. The data-dependency
graph hasn't really changed, so it makes sense that the output
wouldn't change either.

> Another option is a single inline assembly call for the "|=" if the above
> code split does not help.

I've had to do this in a few places, like when I need to atomically
update a hardware flag.

The rest of the code seems to work with your rules, although I have to
shuffle quite a bit of stuff around to accomplish that.

Thanks for your suggestions.

-William

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to