Page 1 of 1

Saving the CPU registers when interrupt occurs after HLT

Posted: Thu Feb 16, 2012 12:41 pm
by limp
Hi again,

I was wondering if it's necessary to save the CPU registers to the stack (pusha) when an interrupt occurs after HLT, i.e. when the last thing executed prior to the interrupt was a HLT instruction.

Are the values of the CPU registers of any use to us in this case?

Thanks

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Thu Feb 16, 2012 12:50 pm
by Combuster
Two apparent assumptions:
when an interrupt occurs after HLT
Does the interrupt handler know that? Specifically, does it know that before it needs to save registers to find out?
Are the values of the CPU registers of any use
Is the code calling HLT expecting to continue? Specifically, is there anything that expects a return from a HLT instruction (i.e. what the interrupt is for) with a given state?

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Thu Feb 16, 2012 12:52 pm
by bluemoon
1. You should preserve registers in interrupt handlers, otherwise if the register changes in interrupt and IRET it interfere the resumed program flow. However there is exception that the interrupt handler act as some kind of services that caller expect result, like syscall.

2. HLT is not relavent.
limp wrote:Are the values of the CPU registers of any use to us in this case?
I don't quite get what you mean. I don't know you but I as a human do not use CPU registers. :?

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Thu Feb 16, 2012 1:05 pm
by limp
Thanks for the replies.
Combuster wrote:
limp wrote:Are the values of the CPU registers of any use
Is the code calling HLT expecting to continue? Specifically, is there anything that expects a return from a HLT instruction (i.e. what the interrupt is for) with a given state?
No, the code calling HLT is not expecting to continue, that's why I asked if in this case is necessary to save the CPU registers (that's what I asked if the values of the CPU registers will be of any use to us in this case). As the function calling the interrupt is not about to continue, I think I can just omit saving them...
Combuster wrote:
limp wrote:when an interrupt occurs after HLT
Does the interrupt handler know that? Specifically, does it know that before it needs to save registers to find out?
I am not quite following you here...if I understood correctly, I think you say if the interrupt handler knows that it will always be executed after a HLT instruction (or a bunch of NOPs if that changes anything) and the answer to that is yes.

Thanks.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Thu Feb 16, 2012 4:35 pm
by Combuster
If the program flow is defined as HLT followed by an external interrupt, then the interrupt handler becomes the process and is at full liberty to do with the registers as it pleases.

If the interrupt can only be called at that specific location in the program flow, the interrupt does not need to check if it has ownership of the registers. That assumption is however very prone to race conditions and may require eventually that you do need a code path that does preserve the registers.

At any rate, it's a hack, meant to work only in non-OS environments. HLTing until a timer interrupt is a good way for idling with the least disturbance of other cores. This method of ending that state is however just asking for trouble in an OS context because you want the timer for other things as well, violating the key assumptions.

As for your original question:
I just want to explore if that is a more efficient way for delaying
Go do something else in the meantime.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Fri Feb 17, 2012 6:24 pm
by TylerH
I'm assuming you plan to use HLT as an exit instruction. I also assume that you want to do that because it would be a very efficient way to allow a task to exit. But, consider that your exit code only gets called once per task and that your timer interrupt handling code gets called about 1000 times per second. The code to check whether the last instruction was HLT would probably amount to more inefficiency (since it gets called so much more) than even a really inefficient exit system call (since it only gets called once).

Regardless of your intent, the point is the same. Adding the code to check for that wouldn't be worth the extra time it would cost in the interrupt handler and might even take more time than just saving the registers (I have no idea if that's true and I don't care enough to look it up. Just an consideration.).

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Fri Feb 17, 2012 8:36 pm
by Jezze
TylerH: I use the hlt instruction in another manner, perhaps the OP is on a simular path I don't know. In my event-driven OS a user space program never puts itself in a busy loop (imagine a shell waiting for a keystroke). Instead they are encouraged to use a "terminate and stay resident" system call. If all running programs are in this mode, and they are 99% of the time except for maybe when a timer interrupt or keyboard interrupt occurs, there is no need to have the CPU running so I put it to halt. I imagine this saves an incredible amount of power compared to a typical multitasking os.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Sat Feb 18, 2012 1:40 am
by TylerH
Jezze wrote:TylerH: I use the hlt instruction in another manner, perhaps the OP is on a simular path I don't know. In my event-driven OS a user space program never puts itself in a busy loop (imagine a shell waiting for a keystroke). Instead they are encouraged to use a "terminate and stay resident" system call. If all running programs are in this mode, and they are 99% of the time except for maybe when a timer interrupt or keyboard interrupt occurs, there is no need to have the CPU running so I put it to halt. I imagine this saves an incredible amount of power compared to a typical multitasking os.
To me, it doesn't make sense for the processor to ever be halted except in the scheduler when there's no task to run. Otherwise, you have a processor halted and tasks waiting to run. It make more sense to have a policy of killing tasks that execute HLT, because they're wasting time they don't have the right to decide to waste. If it only happens in the scheduler, checking for it in the scheduler makes no sense.

BTW, that's a good idea. I've been planning on implementing it in my own OS. A similar, related idea is to provide a system call that allows a task to give up the remainder of it's time and move on to the next task. Unfortunately, I'm nowhere near running tasks.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Mon Feb 20, 2012 10:57 am
by JAAman
Jezze wrote:TylerH: I use the hlt instruction in another manner, perhaps the OP is on a simular path I don't know. In my event-driven OS a user space program never puts itself in a busy loop (imagine a shell waiting for a keystroke). Instead they are encouraged to use a "terminate and stay resident" system call. If all running programs are in this mode, and they are 99% of the time except for maybe when a timer interrupt or keyboard interrupt occurs, there is no need to have the CPU running so I put it to halt. I imagine this saves an incredible amount of power compared to a typical multitasking os.

maybe im missing something here, but that sounds exactly like what most multitasking OSes always do

in normal ordinary multitasking OSs, programs don't "busy loop", instead the tell the OS that they want a key (or, more accurately, tells the OS that it doesn't have anything to do until something happens), and the OS "pauses" the program, so that it never runs until a key has been pressed (or other important event that the program may need to respond to) that is meant for that program, at which time the OS will wake up the program -- in this way, the program is never run unless it specifically has something important to do -- the rest of the time, the program is suspended and the OS can schedule other programs to run

in this way, only programs that have important things to do are ever running, and no program is ever wasting time busy looping or polling something, and the OS can wake the program only when an important event occurs (which may be keypresses, mouse movement/clicking, or the screen being erased and needing to be redrawn, amongst many other things) and only the necessary programs -- for instance, the shell has no need to be woken up if the keyboard is used to type in a word-processor, only if the keypresses are intended for the shell (or if, for some reason, your shell tells the OS that it needs to intercept all keys destined for all processes, rather than only its own -- but most programs won't need anything like this

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Mon Feb 20, 2012 12:09 pm
by Jezze
Yeah you are probably right, the difference is not that great.

I imagine, and I might be wrong on this, is that a multitasking os is somewhat dependent on a timer that will in regular intervals fire and let the os know it might be time to reschedule or do some other sort of task. This will fire up the CPU of course (how else would it do the processing) and then if no task is ready to run it can return to it's halted state.

The difference with the event-driven approach is that there is no dependency on a timer in the os. If you are not touching any keys on the keyboard there is absolutly nothing running so the total uninterrupted sleeping (halted) period for the CPU is longer.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Mon Feb 20, 2012 12:41 pm
by bluemoon
In modern OSes they use both method.

The timer is a deadline, the maximum duration of each process before it got switched out; however the timer is usually in scale of ms, and you usually have more than a thousand processes.

So, there are more ways to trigger process switch, either the application give up its time slice (yield) or it call some syscall.

Re: Saving the CPU registers when interrupt occurs after HLT

Posted: Mon Feb 20, 2012 12:53 pm
by JAAman
Jezze wrote: The difference with the event-driven approach is that there is no dependency on a timer in the os. If you are not touching any keys on the keyboard there is absolutly nothing running so the total uninterrupted sleeping (halted) period for the CPU is longer.

no, event-driven systems do not need to run the timer at regular intervals

the timer is basically only used if
1) a process has requested to be woken at a specific time (say a clock wants to update every second, or a video player wants to create a frame x-times-per-second)
2) a process is currently running, and the OS wants to make sure it doesn't use more than its own fair share of CPU time, in which case the timer is used to preempt execution of a thread that never asks to be put to sleep in the first place (perhaps a heavy processing program, or a game which wants to just keep creating new frames)

in the former case, a thread needs to be woken anyway, and therefore there is no waste of waking the core, in the later case, the core is already awake, and thus while it might theoretically slow the system down a bit, it is generally preferred rather than allowing a single bad thread to lock up the system

in other cases, the timer won't be used to wake the core, rather another interrupt will be -- such as, it might be woken from the keyboard interrupt, or an interrupt from the HDD, or some other device signaling that its done or ready/waiting, or whatever the case might be, in which case, it is likely that some process is waiting for that device anyway, or it might be woken from another CPU/core (using an IPI) to change what the core is doing for whatever reason -- this is, in fact, how sleep-states in modern cores work anyway, if there were constantly timers going off, then there would be no ability for the CPU to use its deeper sleep-states -- if the OS knows that it will be sleeping for a while (or that it can sleep for a while, by scheduling all threads for other cores), it will put the core into a deeper sleep-state -- these deeper sleep-states usually take much longer to enter/leave, and thus shouldn't be used for very short times