Hello!
I recently discovered a problem that affects my entire code base. I
often do things like this:
volatile unsigned char state;
...
state |= (state >> 1) & DIRTY_FLAG;
Since ISR's might be trying to set DIRTY_FLAG at the same time, it is
very important that the final "|=" instruction happens atomically,
like with a "BIS.B foo, &state" instruction. This was my original
expectation, but the compiler apparently generates code like this
instead:
MOV.B &state, R15
MOV.B &state, R14
RRUM #0x0001, R15
AND.B #0x0002, R15
BIS.B R14, R15
MOV.B R15, &state
As you can see, there is a window of about three instructions where
changes from an ISR would be lost. I could surround this code with
__eint() / __dint() calls, but that seems overkill. I really want the
compiler to generate code like this:
MOV.B &state, R15
RRUM #0x0001, R15
AND.B #0x0002, R15
BIS.B R15, &state
Besides being smaller and faster, this actually does the right thing.
So, what do I do? Short-term options include rewriting the critical
bits in assembly and/or inserting the __eint() / __dint() calls, but I
am really looking for a more elegant long-term solution. Fixing the
code generator would be one option, but adding set of intrinsics like
__atomic_add() would also be nice, since those would document the
intention as well.
-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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users