Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
DavidCooper wrote:What is the correct way to use the HLT instruction?
The "correct" way, in my opinion, would be to let the OS call the HLT instruction, and only when there is no work to be done.
Yes, and my question is about how the OS uses the HLT instruction in that circumstance - it has determined that there is no work needing to be done, so it branches off into the code containing the HLT instruction and if an interrupt happens at that point, what happens? The interrupt routine sets things up for some new work to be done, but typically doesn't carry it all out within the interrupt routine itself, so what happens on iret? It runs straight into the HLT instruction and there may not be another interrupt to wake the processor for some time.
So, you don't have to worry about the CPU being "asleep" if there is actually work to do. An interrupt will always wake it back up.
I'm talking about a rare case where the timing is bad, the interrupt coming just before the HLT instruction is run.
The canonical way is to actually have the sleep task as a separate task, so that if the consequence of the interrupt is that there is better work to be done, it does not actually return to the halt statement.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Combuster wrote:The canonical way is to actually have the sleep task as a separate task, so that if the consequence of the interrupt is that there is better work to be done, it does not actually return to the halt statement.
Right, so that must mean you are supposed to change the ret address for the iret and that all interrupt routines should be capable of doing this.
That sounds more elaborate than necessary. Every interrupt handler should simply be able to initiate a task switch. You'll need that feature anyway as you can't properly do thread priorities without it either.
Considering the canonical task switch is a stack switch, no return addresses actually need to be modified.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Combuster wrote:That sounds more elaborate than necessary. Every interrupt handler should simply be able to initiate a task switch. You'll need that feature anyway as you can't properly do thread priorities without it either.
Considering the canonical task switch is a stack switch, no return addresses actually need to be modified.
Thanks - I get it now. I'm still using primitive co-operative multitasking at the moment and I hadn't thought through how it works with the preemptive type.
(As for why I use co-operative multitasking, I used to have to run my OS with the interrupts disabled all the time - that was before I had access to the Internet, so I couldn't get information on how to use interrupts and didn't have any choice. Although I use interrupts now, I can still disable them at any time and have the OS continue multitasking as if nothing happened, but it's not a useful trick. I'll switch over to using preemptive multitasking at some point when I have more time.)
DavidCooper wrote:my question is about how the OS uses the HLT instruction in that circumstance - it has determined that there is no work needing to be done, so it branches off into the code containing the HLT instruction and if an interrupt happens at that point, what happens? The interrupt routine sets things up for some new work to be done, but typically doesn't carry it all out within the interrupt routine itself, so what happens on iret? It runs straight into the HLT instruction and there may not be another interrupt to wake the processor for some time.
As I see it - HLT instruction is executed as any other instruction, it means the instruction pointer is incremented after processor consumed the HLT. Next comes an interrupt. Processor starts working (resumes from halted mode), pushes instruction pointer and flags to the stack and next loads instruction pointer value from IDT. After IRET, because the stack contains instruction pointer AFTER the HLT instruction, the program runs smoothly as is the case for every other instruction.
My previous account (embryo) was accidentally deleted, so I have no chance but to use something new. But may be it was a good lesson about software reliability
DavidCooper wrote:my question is about how the OS uses the HLT instruction in that circumstance - it has determined that there is no work needing to be done, so it branches off into the code containing the HLT instruction and if an interrupt happens at that point, what happens? The interrupt routine sets things up for some new work to be done, but typically doesn't carry it all out within the interrupt routine itself, so what happens on iret? It runs straight into the HLT instruction and there may not be another interrupt to wake the processor for some time.
As I see it - HLT instruction is executed as any other instruction, it means the instruction pointer is incremented after processor consumed the HLT. Next comes an interrupt. Processor starts working (resumes from halted mode), pushes instruction pointer and flags to the stack and next loads instruction pointer value from IDT. After IRET, because the stack contains instruction pointer AFTER the HLT instruction, the program runs smoothly as is the case for every other instruction.
Did you not read the question? What happens if the interrupt occurs before the HLT instruction has executed?
If a trainstation is where trains stop, what is a workstation ?
I don't really understand the question. It would be a very poor OS design that indicated that there was no work to be done when the interrupt routine had determined that there was.
In any case, the timer interrupt will happen at regular intervals to reawaken the processor (as long as interrupts are not disabled - but that should only happen within the interrupt routine itself).
Did you not read the question? What happens if the interrupt occurs before the HLT instruction has executed?
If you read the half page of conversation since the original remark, you'll see that it is actually an issue, it is caused by an assumed implementation detail, and there are suggestions on how to solve it properly.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Interrupts off - From interrupt handler or from cli; in main program
Doing stuff to check if something needs to be done.
Stuff needs to be done, either return from interrupt to another task (Your time is up program, time to slice) or switch task in main program (User wants to sleep, etc, I use SYSRETQ), enable interrupts on return, set page tables, etc...
Or, nothing to do, go into halt. sti; hlt; cli
After halt code check for something to do, eg, loop from step #2, or a quick pointer check.....
Thanks - I'll use that. It's probably a better way of doing it than having a halt task as it'll go to sleep a fraction sooner and get back to doing real work more quickly too.