[En-Nut-Discussion] Not fixed!!!: Re: confirmed!!! Re: NutOS 4.4.0 on ARM7: possibly bug in NutEnterCritical / NutExitCritical

Nathan Moore nategoose at gmail.com
Fri Feb 22 21:43:43 CET 2008


>
> Is there a real reason why passing a variable would hurt? Defining a
> special (hardware specific) type like "crit_section_t" would help us to
> be compatible with later inventions and ports too.


As far as I can see the only real reason not to would be because it would
impose more work on the developers using the critical sections.
This is how I implemented my macros -- they have a typedef, and each arch
would have to define their own type.
For most general cases using a local variable to hold the state would also
generate smaller and faster code since it usually wouldn't have to do the
push/pop instructions.


--------------------------------------------------------------------------------------------------------------------------------------------------------
/* New avr atomic operations using a Critical variable to hold the
 * interrupt state so that it can be restored upon leaving the
 * critical section.
 */


#ifdef __IMAGECRAFT__

typedef unsigned char Critical;

#define NutGetCritical( C )                                     \
    do {                                                     \
        C = inb(SREG);                                    \
        asm( "cli\n" );                                   \
    } while (0)

#define NutGiveUpCritical( C )                                  \
    do {                                                     \
        outb(SREG, C);                                    \
    } while (0)


#elif __GCC__

#define NT "\n\t"

typedef unsigned char Critical;

/* This uses a local variable declared as a Critical to both give
 * the compiler flexability in optimization and encourage type
 * checking.  Extra mov instructions will be optimized away.
 */
#define NutGetCritical( C )                                         \
    do {                                                             \
        register Critical _c;                                 \
        asm volatile (                                        \
            "/* begin of NutGetCritical */"         NT    \
             "in %0, __SREG__"                       NT    \
            "cli"                                   NT    \
            "/* end of NutGetCritical */"           NT    \
            : "=r" (_c)                                   \
            : /* no input */                              \
        );                                                    \
        C = _c;                                               \
     } while (0)


#define NutGiveUpCritical( C )                                    \
    do {                                                       \
        register Critical _c = C;                           \
        asm volatile (                                       \
            "/* begin of NutGiveUpCritical */"      NT    \
            "out __SREG__, %0"                      NT    \
            "/* end of NutGiveUpCritical */"        NT    \
            : /* no output */                             \
            : "r" (_c)                                    \
        );                                                    \
    } while (0)

#undef NT

#endif /* Compiler Vendor */



More information about the En-Nut-Discussion mailing list