void casts in save/restore context macros

stephencleary wrote on Wednesday, March 30, 2011:

In the GCC/ARM7_AT91SAM7S port, both the portSAVE_CONTEXT and portRESTORE_CONTEXT macros declare variables (pxCurrentTCB and ulCriticalNesting) that are cast to void, presumably to avoid a compiler warning.

However, since the variables are declared volatile, the compiler is dutifully generating code to read them and discard the values. Here’s the disassembly for vPortISRStartFirstTask (which only calls portRESTORE_CONTEXT), as compiled by Rowley (gcc 4.4.5) in release mode:

    E59F0240    ldr r0, 0x00000248 // First line of portRESTORE_CONTEXT macro
    E5900000    ldr r0,
    E590E000    ldr lr,
    E59F0238    ldr r0, 0x0000024C
    E8BE0002    ldm lr!, {r1}
    E5801000    str r1,
    E8BE0001    ldm lr!, {r0}
    E169F000    msr spsr_cf r0
    E8DE7FFF    ldmia lr, {r0-lr}^
    E1A00000    mov r0, r0
    E59EE03C    ldr lr,
    E25EF004    subs pc, lr, #4 // Last line of portRESTORE_CONTEXT macro
    E59F300C    ldr r3, 0x00000044
    E5933000    ldr r3,
    E59F3008    ldr r3, 0x00000048
    E5933000    ldr r3,
    E12FFF1E    bx lr // Start of standard epilogue (also unnecessary)
    00000000    andeq r0, r0, r0
    00000000    andeq r0, r0, r0

The portSAVE_CONTEXT macro has a similar problem, and actually executes the instructions.

I believe __attribute__((unused)) and possibly also __attribute__((noreturn)) could be used to reduce some of the generated code (and make for slightly faster context switches since portSAVE_CONTEXT currently always executes 4 noops).