Questions about hlt instruction

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.
Post Reply
tom1000000

Questions about hlt instruction

Post by tom1000000 »

Hi,

I am under the impression that when you have an idle thread it should use the hlt instruction to "pause" the cpu.

Question 1:

If an idle thread gets halted, and an interrupt for the disk occurs (as an example), does cpu resume at the instruction after the hlt instruction, or does it jump to the irq code?

If it resumes the code after the hlt, isn't that an unserviced interrupt?

Question 2:

It seems that hlt can only be executed by code at CPL0. What happens if you want ALL threads to run at CPL3 (using the IOPL in eflags to give access to hardware for device driver threads)? Do I have to create a "special" thread just so I can hlt the system? Is there another way??

Thanks!
RicoSanchez

Re:Questions about hlt instruction

Post by RicoSanchez »

Answer 1:

If the CPU is in a halted state (by the hlt opcode) and an interrupt occurs, the CPU handles the interrupt. After serving the interrupt and doing an iret the code right after the hlt instruction gets executed. So no, all interrupts are serviced. A simple piece of code of the idle thread whould be:

Code: Select all

halt:   hlt
        jump halt
This will be an endless idle loop.

Answer 2:

If the hlt instruction only works in CPL0, then you can't run the idle thread in any other CPL other than CLP0. And I tought CPL3 can't even do in and out instructions, I tought only CPL1 and CPL2 can do in and out instructions with the IOPL flag. But the choice of running all threads in CPL3 isn't clear to me anyways.
tom1000000

Re:Questions about hlt instruction

Post by tom1000000 »

Hi thanks for your answers.

FYI you can allow in/out etc at CPL level 3. Just set the IOPL in the eflags register to 3. I think you have to be at CPL0 to SET the IOPL but after that in/out can be used at CPL3. Unless I have made a mistake reading the intel manuals????
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Questions about hlt instruction

Post by Pype.Clicker »

i also understood it that way ... but it's been a long time since i refreshed that section in /dev/brain :)
RicoSanchez

Re:Questions about hlt instruction

Post by RicoSanchez »

Tommy, yes, you are probably right. I was confusing it the way I want to implement it myself, and that is to not allow I/O in CPL3.
Beth

Re:Questions about hlt instruction

Post by Beth »

tom1000000 wrote: I am under the impression that when you have an idle thread it should use the hlt instruction to "pause" the cpu.
You're almost there...what most OSes actually do is establish a "system idle thread" that's delibrately given the lowest possible priority (lower than any other thread)...this thread just issues HLT in an infinite loop...yes, when an interrupt occurs, it'll go to service the interrupt and not return to the instruction after HLT...and, yes, HLT is a ring0 instruction so only kernel code should be issueing it...but, Hopefully, you can see that, under this design, these restrictions aren't a problem at all...

Individual threads going idle aren't supposed to be calling HLT themselves...instead, they should block on something (say, some sort of "WaitForMessageInQueue" API, which automatically blocks a thread until it receives a message about user input)...when all of the threads have blocked, the ordinary scheduler code will automatically be selecting this "system idle" thread because it has the lowest priority (and, strictly, it is the only thread in the system that delibrately _never_ blocks and is _always_ running...but because it has lowest priority, it'll never be running if there's anything else that wants the CPU...all other threads are more important - having a higher priority - and always override the "system idle" thread)...

The "system idle" thread has no purpose other than to issue HLT in an infinite loop to give the CPU a rest - to cool down and save power - whenever nothing else is happening...only this thread needs to issue HLT and it's going to be a kernel routine with ring0 priviledge...the "system idle thread" could not bother with HLT and just loop around an infinite loop to give the CPU something to do while it waits for things to happen but this isn't recommended...HLT actually puts the CPU into "pause mode", as you say, and uses less power and lets the CPU "rest" to cool down...that seems the infinitely more sensible thing to be having the CPU do when there's nothing else to be doing and that's the designed purpose of the HLT instruction...

So, you got the basic idea right but the point to stress is that HLT is for when the _entire system_ goes idle, not individual threads...when they go idle, we just want to be going straight to some other thread in the system that wants attention...so, _block_ idle threads...HLT will only be issued when all of them block and the "system idle" thread is automatically scheduled using normal priority-based scheduling (if your scheduling is not priority-based then, instead, merely devise your own way of only calling this thread when nothing else needs the CPU...priorities, though, are the simple, most often used way of doing this)...

Umm, Hope that clarifies rather than confuses,
Beth :)
Post Reply