Christian Thaeter
2015-11-25 21:55:11 UTC
I've come into a situation where I may call a function with from
undefined interrupt enable state where I want to call some inner things
with the state the interrupt had on entry of the function. It would be
nice to have some way to restore the 'outer' state for that
like in this example:
void
myfunction ()
{
// interupt state not known here, but saved
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
..do something..;
if (blah)
{
..do something..;
// restore interupt state as it was on the enclosing ATOMIC_BLOCK
RESTORE_ATOMIC_BLOCK
{
..do something..;
}
..do something..;
}
..do something..;
}
}
as you can see it's not trivially possible to use 2 ATOMIC_BLOCK's after
each other because of the if statement.
So here is the code to make that happen:
-------------- add to util/atomic.c: ----------------------------------
static __inline__ uint8_t __iOuter(const uint8_t *__s)
{
SREG = *__s;
__asm__ volatile ("" ::: "memory");
return 1;
}
...snip...
#define RESTORE_ATOMIC_BLOCK for ( uint8_t __restore __attribute__((__cleanup__(__iCliParam))) = 0, \
__ToDo = __iOuter(&sreg_save); \
__ToDo ; __ToDo = 0 )
#define RESTORE_NONATOMIC_BLOCK for ( uint8_t __restore __attribute__((__cleanup__(__iSeiParam))) = 0, \
__ToDo = __iOuter(&sreg_save); \
__ToDo ; __ToDo = 0 )
-------------- end of util/atomic.c: ----------------------------------
Would you like to merge such? Any comments are welcome. When you are positive about this
feature I'll prepare patches in proper format with some documentation.
greetings
Christian
undefined interrupt enable state where I want to call some inner things
with the state the interrupt had on entry of the function. It would be
nice to have some way to restore the 'outer' state for that
like in this example:
void
myfunction ()
{
// interupt state not known here, but saved
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
..do something..;
if (blah)
{
..do something..;
// restore interupt state as it was on the enclosing ATOMIC_BLOCK
RESTORE_ATOMIC_BLOCK
{
..do something..;
}
..do something..;
}
..do something..;
}
}
as you can see it's not trivially possible to use 2 ATOMIC_BLOCK's after
each other because of the if statement.
So here is the code to make that happen:
-------------- add to util/atomic.c: ----------------------------------
static __inline__ uint8_t __iOuter(const uint8_t *__s)
{
SREG = *__s;
__asm__ volatile ("" ::: "memory");
return 1;
}
...snip...
#define RESTORE_ATOMIC_BLOCK for ( uint8_t __restore __attribute__((__cleanup__(__iCliParam))) = 0, \
__ToDo = __iOuter(&sreg_save); \
__ToDo ; __ToDo = 0 )
#define RESTORE_NONATOMIC_BLOCK for ( uint8_t __restore __attribute__((__cleanup__(__iSeiParam))) = 0, \
__ToDo = __iOuter(&sreg_save); \
__ToDo ; __ToDo = 0 )
-------------- end of util/atomic.c: ----------------------------------
Would you like to merge such? Any comments are welcome. When you are positive about this
feature I'll prepare patches in proper format with some documentation.
greetings
Christian