Page 1 of 1

Resumed program execution after sleep

Posted: Sun Jan 26, 2014 12:27 pm
by limp
AFAIK, if a processor is put to sleep before the occurrence of the next interrupt, it should (commonly?) resume the program execution from where it’s left off (i.e. from the instruction that immediately follows the "put to sleep" instruction) after the end of the ISR (executed when it next "wakes-up" from sleep). So, if a function call like the following was used to put the system to sleep…

Go_to_Sleep();
where Go_to_Sleep() is defined as:
void Go_to_Sleep(void)
{
asm volatile("HLT");
}
… the processor should actually return (exit) from the Go_to_Sleep() function before continuing with the execution of anything else (although there isn’t anything following the asm volatile("HLT"); code).

So, my question is: Would the processor actually need to do this “extra” step or not? I guess that if we use any sort of compiler optimisation, this might be avoided, but if we don’t, I think this extra (probably tiny) overhead exists.

Any ideas will be greatly appreciated.

Re: Resumed program execution after sleep

Posted: Sun Jan 26, 2014 1:15 pm
by DavidCooper
What does your compiled machine code look like? Do you end up with a call to a routine containing a halt instruction followed by a ret instruction or does the compiler eliminate the call altogether and just stick a halt instruction straight into the stream of code? If it does the former, there's an interesting question as to whether the processor works on ahead to find a better point to continue from when the next interrupt frees it up to start running again, but if it doesn't, the delay will be tiny and isn't worth worrying about.

There's something much more significant to think about with using a halt instruction, and that is that an interrupt could occur just before the halt instruction is run, so the iret will lead straight back to the halt instruction and stop the processor just at the moment when there may be urgent work needing to be done - if the interrupt routine doesn't do the work itself but merely tells or sets up a thread to do the work, that work won't be done until another interrupt comes in much later on to wake up the processor again.

Re: Resumed program execution after sleep

Posted: Sun Jan 26, 2014 1:27 pm
by Combuster
limp wrote:where Go_to_Sleep() is defined as:

Code: Select all

void Go_to_Sleep(void)
{
    asm volatile("HLT");
}
What HLT does is increment the instruction pointer like pretty much every other instruction and wait until an interrupt happens. It simply happens to conserve energy, but is also about the least of sleep states you can get, although it does work on every processor.

This function should compile to something like the following (unless the compiler adds it's standard payload of crap):

Code: Select all

go_to_sleep:
    HLT
    RET
Which means that when the interrupt is served, the stack points to "RET" as the next instruction, so it does not magically skip anything.

A better compiler will actually inline the HLT opcode which means you save exactly one CALL and one RET. However, if you go to sleep you don't have anything to do anyway so those few cycles you spend around HLT are utterly meaningless compared to the amount of cycles HLT will make you spend waiting.