On 03/09/2012 19:54, JMGross wrote: > > ----- Ursprüngliche Nachricht ----- > Von: David Brown > Gesendet am: 03.September.2012 13:01:31 > >> On 03/09/2012 00:10, William "Chops" Westfield wrote: >>> AVR has >>> http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html >>> As far as I know, it just inserts appropriate disable/reenable >>> interrupt instructions. > >> Yes, the AVR "atomics" are exactly about disabling interrupts around a >> block of instructions (like mspgcc's "critical" function attribute). > >> There is no way a peephole optimiser could change a DINT/<opcode>/EINT >> set. The set of instructions has a different effect from the <opcode> >> on its own - namely it also enables interrupts. > > indeed, that's a side-effect of many 'cheap' implementations of an atomic > block. > This is why the mentioned AVR atomic macro collection provides different > parameters on how to deal with this. > > The apparent solution is to store the current state on the stack. > But this has some disadvantages too. > Mainly that it takes two bytes on the stack. Since you don't know > how many nested sections you might have (an atomic block > only means it isn't interrupted, but this does not imply that it has to be > short or won't call functions), you'll end up with a stack overflow due to > the added status register contents.
You would have to have a truly bizarre structure to have so many nested "atomic" blocks to use up stack space of any relevance. And if you are that close to overflowing your stack, then any interrupts called outside the atomic block will be a much bigger risk. And in real-world code, atomic blocks are small - the status register is not saved on the stack but held in a temporary register. > Also, saving the status register > and restoring it, will also restore the content of all other bits, not just > GIE. True, but that won't matter. Compilers do not usually track the state of status bits over a longer range than one instruction pattern. > And finally, at least with MSPGCC 3.2.3, I found situations where the > compiler didn't like the status register being changed by the push > because of the influence it had on the reference to local variables. > (in cases where the optimizer optimized R4 as frame pointer away in > favor of R1). I didn't find a way to tell that R1 is changed in the course > of the assembly instruction. This sounds like an old bug in an old compiler version. > > Isolating the state of GIE and writing it into a global variable doesn't > allow nesting and also adds soem code overhead. > > So I have come up with a macro that uses a global counter to count > the nesting level. It will only perform an eint if the counter reaches 0 > on block exit. > This of course assumes that interrupts are on outside the first atomic > block and that no dint/eint operations are uses within. > > unsigned int ATOMIC_CNT; > #define ATOMIC(x) do { __asm__ __volatile__ ("inc %0\n dint\n > ":"=m"(ATOMIC_CNT):); x; __asm__ __volatile__ ("dec %0\n > jnz .LA%=\n eint\n .LA%=:":"=m"(ATOMIC_CNT):);}while(0) > Sometimes these sorts of solutions can be useful - but usually simpler methods are best. > However, even with GIE clear, an operation can still be interrupted by > NMI or DMA. NMI's are seldom used, except sometimes for handling real disasters, but it is a very important point to remember that DMA operations are independent of the CPU and any "atomic" handling. > Only for single RMW operations, none of the two can interrupt them. > And for DMA, only if the DMA is programmed to not do it. > Also, only for single RMW instructions, you know hwo much time > will pass between the read and the write. If the operation is spread > across multiple instructions, even though not interrupted, you > don't know how much time it takes. And sometimes, this is critical. > Usually, when dealing with multi-flag hardware registers. > Too often, Beginners aren't aware of this or simply don't care, > assuming a 'simple' C instruction resulting in an evenly 'simple' > binary code. > > The macros Peter posted are a good extension of the language > and ot less portabel than an intrinsic :) > > JMGross > ------------------------------------------------------------------------------ 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