Author Topic: [AVR] Wrapping a function return statement in ATOMIC_BLOCK  (Read 212 times)

0 Members and 1 Guest are viewing this topic.

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 633
  • Country: gb
[AVR] Wrapping a function return statement in ATOMIC_BLOCK
« on: October 04, 2019, 12:45:12 am »
I have a simple function, where all it needs to do is return a volatile multi-byte (uint32_t) global variable. Of course, being prudent, I should use the appropriate mechanisms to access this variable atomically, using ATOMIC_BLOCK. But, it seems inefficient to me to copy the global variable into a local variable inside the atomic block, then return the local one.

So, the question is, can I do the following?

Code: [Select]
uint32_t get_foo() {
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        return foo; // A global volatile uint32_t
    }
}

I understand that ATOMIC_BLOCK uses some macro and compiler magic to ensure that SREG is saved and restored no matter what exit path from the block is taken, but does this apply to a return?

I took a look at the resultant assembly, and I think it's doing what it should, but I would be happy if someone more knowledgeable of AVR assembler were to look at it and confirm.

Code: [Select]
00000712 <get_foo>:
     712: 2f b7        in r18, 0x3f ; 63
     714: f8 94        cli
     716: 60 91 03 02 lds r22, 0x0203 ; 0x800203 <foo>
     71a: 70 91 04 02 lds r23, 0x0204 ; 0x800204 <foo+0x1>
     71e: 80 91 05 02 lds r24, 0x0205 ; 0x800205 <foo+0x2>
     722: 90 91 06 02 lds r25, 0x0206 ; 0x800206 <foo+0x3>
     726: 2f bf        out 0x3f, r18 ; 63
     728: 08 95        ret

If I'm understanding this correctly, it's saving SREG in r18, disabling interrupts, copying foo into function return registers, restoring SREG, and finally returning.

If this is all correct and hunky-dory, and follows my intention to atomically access the foo variable, then great. :D All I need to do is take care of the compiler warning saying "control reaches end of non-void function". I guess I could whack in a second return statement (that will never be reached) outside the block.
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 14135
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [AVR] Wrapping a function return statement in ATOMIC_BLOCK
« Reply #1 on: October 04, 2019, 01:13:55 am »
This discusses the warning (and the same situation):
https://www.avrfreaks.net/forum/atomicblock-control-reaches-end-non-void-function

You can use a temporary variable, as listed above.

Or: don't put it in a function at all.  If this example is truly all that the function contains, then it is a trivial example, and should either be inlined (on -O3, this will probably happen automatically), put into a macro (#define get_foo ...), or just pasted into the calling function verbatim. :)

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 633
  • Country: gb
Re: [AVR] Wrapping a function return statement in ATOMIC_BLOCK
« Reply #2 on: October 04, 2019, 01:44:49 am »
Coincidentally I found and have just been reading that linked thread. :)

Yes, even though it's a trivial function, I need it to be a function because it will be a callback function pointer that is passed to something else. In fact, I have specifically marked it with an attribute to prevent it being inlined.

I just tried putting in a second return statement ("return 0;" after the atomic block), and the compiler actually ignores it and emits no additional instructions for it.

So, I guess I just need to know if the assembly I posted previously is actually doing the right thing. Hopefully someone can confirm my interpretation.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 476
Re: [AVR] Wrapping a function return statement in ATOMIC_BLOCK
« Reply #3 on: October 04, 2019, 02:29:34 am »
https://godbolt.org/z/B_y4c3

Compilers are pretty smart, so usually no need to try to out-think it.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3077
  • Country: us
Re: [AVR] Wrapping a function return statement in ATOMIC_BLOCK
« Reply #4 on: October 04, 2019, 11:09:49 pm »
I  lot of compilers will implement a "return" in the middle of a function as a jump to the function epilogue, anyway.  (that way they only need the epilogue once.)  So all that's needed is to make sure that the re-enable of interrupts happens gets added to what gcc considers the epilogue of the function.   IIRC, ATOMIC_BLOCK actually does some magic to make sure that this is the case...
Ah, yes.  See https://blog.oddbit.com/post/2019-02-01-atomicblock-magic-in-avrlibc/
 
The following users thanked this post: ledtester


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf