Software task switch - interrupted ISR
Software task switch - interrupted ISR
Hello!
There is a lot of information about software task switch, but I can't understand one thing: we store context in the timer interrupt, supposing that this is interrupted task context, but when the timer interrupt interrupts some other interrupt handler? What about this case?
There is a lot of information about software task switch, but I can't understand one thing: we store context in the timer interrupt, supposing that this is interrupted task context, but when the timer interrupt interrupts some other interrupt handler? What about this case?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Software task switch - interrupted ISR
In many cases interrupts are prevented from nesting altogether, or operations are postponed until the last interrupt handler completes.
Re: Software task switch - interrupted ISR
Sorry, but I don't understand your idea. In all sources, I've seen before, the timer interrupt can interrupt, for example, kbd ISR (IRQ with less priority)... and I think that it is right.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Software task switch - interrupted ISR
Interrupts have priority over normal tasks. The scheduler deals with normal tasks, therefore executing interrupts should have some priority over the scheduler as well.
Specifically you do not want a task switch out of an interrupt handler, because it means that that interrupt, and any lower-priority ones will only be serviced when the original task is run again, which can result in several IRQs being missed.
Specifically you do not want a task switch out of an interrupt handler, because it means that that interrupt, and any lower-priority ones will only be serviced when the original task is run again, which can result in several IRQs being missed.
Re: Software task switch - interrupted ISR
OK, but I again miss a main idea. I'll try to explain what I want to understand:
suppose, I have a routine void switch_task(struct task *next_task) and global variable struct task *current_task. switch_task() do a software context switch from current_task to the next_task and can be invoked from: timer ISR (when the task time slice is expired), system call ISR (syscalls: sleep, exit, wait, yield). So, I wonder what can I do when timer ISR interrupts not task but some other ISR (for example, keyboard ISR)?
suppose, I have a routine void switch_task(struct task *next_task) and global variable struct task *current_task. switch_task() do a software context switch from current_task to the next_task and can be invoked from: timer ISR (when the task time slice is expired), system call ISR (syscalls: sleep, exit, wait, yield). So, I wonder what can I do when timer ISR interrupts not task but some other ISR (for example, keyboard ISR)?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Software task switch - interrupted ISR
suslik wrote:So, I wonder what can I do when timer ISR interrupts not task but some other ISR (for example, keyboard ISR)?
Same question, same answer. I'm at work so I can't just post a pageful to cover any lack of understanding or reading skills you might have.In many cases interrupts are prevented from nesting altogether, or operations are postponed until the last interrupt handler completes.
Re: Software task switch - interrupted ISR
You could keep a variable (counter) in the scheduler for the number of nested IRQs. Whenever an ISR is entered, you increase it, and enable interrupts. When the ISR exists, it disables interrupts and decrease the counter. The scheduler will then check this variable when doing context switches, and if it is non-zero, it will not switch task. You probably need to combine it with a function to do delayed context switches when the last IRQ exists. I also combine this function with doing wakeups of tasks from IRQs.
Alternatively, you never enable interrupts in ISRs. Then no other IRQs can fire.
Alternatively, you never enable interrupts in ISRs. Then no other IRQs can fire.
Re: Software task switch - interrupted ISR
If you have kernel stack per thread (which is easier but not the best design), you can invoke scheduler at any place, then you just need to disable interrupt when performing switch:
Code: Select all
pushf
cli
save state (with flags before cli)
pick next
load state (interrupt flag restored for new process)
Re: Software task switch - interrupted ISR
To disable IRQs in the (possibly) nested IRQ does no good. If any IRQs can run with interrupts enabled, your task-switch IRQ might happen during that time, and then you will switch-away from the IRQ that happened in the old thread.bluemoon wrote:If you have kernel stack per thread (which is easier but not the best design), you can invoke scheduler at any place, then you just need to disable interrupt when performing switch:Code: Select all
pushf cli save state (with flags before cli) pick next load state (interrupt flag restored for new process)
BTW. I use one kernel stack per thread.
Re: Software task switch - interrupted ISR
OK, I think to make something like this:
is not good, since when ISR is time consuming I lose some timer interrupts. And timer interrupt can occure right before cli in ISR beginning (or it can not?).
I know nothing about "one kernel stack per task", but before I begin to study this technique I want to understand how others implements "software context switch with kernel stack per each task". I've seen Simplix OS sources and realized that the moment of interrupted ISR by timer interrupt is not clear for me.
Code: Select all
ISR:
cli
...
sti
iret
I know nothing about "one kernel stack per task", but before I begin to study this technique I want to understand how others implements "software context switch with kernel stack per each task". I've seen Simplix OS sources and realized that the moment of interrupted ISR by timer interrupt is not clear for me.
Re: Software task switch - interrupted ISR
This will work just as well:suslik wrote:OK, I think to make something like this:is not good, since when ISR is time consuming I lose some timer interrupts. And timer interrupt can occure right before cli in ISR beginning (or it can not?).Code: Select all
ISR: cli ... sti iret
Code: Select all
ISR:
...
iret
The alternative (locking scheduler) looks something like this: (int_nesting starts as -1)suslik wrote:I know nothing about "one kernel stack per task", but before I begin to study this technique I want to understand how others implements "software context switch with kernel stack per each task". I've seen Simplix OS sources and realized that the moment of interrupted ISR by timer interrupt is not clear for me.
Code: Select all
ISR:
add int_nesting,1
sti
...
cli
sub int_nesting,1
jnc isr_leave
DoPossiblyDelayedTaskSwitch
isr_leave:
iretd
Re: Software task switch - interrupted ISR
rdos, I forget about: "The difference between interrupt gates and trap gates is that for interrupt gates, interrupts are automatically disabled upon entry and reenabled upon IRET which restores the saved EFLAGS". I use interrupt gates in my IDT and I've belived that interrupt with greater priority interrupts one with less priority. In Simplix interrupt gates are used for hardware interrupts too, so there is no need for worrying about interrupted ISR.
I need to know if it is right to use not nested interrupts?
I need to know if it is right to use not nested interrupts?
Re: Software task switch - interrupted ISR
> jnc isr_leave
Did you mean jnz?
Also, I don't remember exactly, but add/sub instr-s don't have implicit lock. Why not inc/dec?
Ontopic: afaik, people avoid doing heavy things in hardware interrupts' handlers. Handler just adds some data to irq data queue and exits. So, you don't have to think about nested interrupts and possibility to miss some of them.
Did you mean jnz?
Also, I don't remember exactly, but add/sub instr-s don't have implicit lock. Why not inc/dec?
Ontopic: afaik, people avoid doing heavy things in hardware interrupts' handlers. Handler just adds some data to irq data queue and exits. So, you don't have to think about nested interrupts and possibility to miss some of them.
Re: Software task switch - interrupted ISR
Regardless of design, you should always use interrupt gates. Otherwise, the ISR might be switched from before you can execute cli.suslik wrote:rdos, I forget about: "The difference between interrupt gates and trap gates is that for interrupt gates, interrupts are automatically disabled upon entry and reenabled upon IRET which restores the saved EFLAGS". I use interrupt gates in my IDT and I've belived that interrupt with greater priority interrupts one with less priority. In Simplix interrupt gates are used for hardware interrupts too, so there is no need for worrying about interrupted ISR.
There is no right or wrong about that. It is a design-decision that is linked to several other issues.suslik wrote:I need to know if it is right to use not nested interrupts?
Some of the issues:
1. If you keep interrupts disabled, you need to keep interrupts short. That might be hard to do for complex devices that might chain each others (for instance, several PCI devices can use the same IRQ).
2. If you want to signal from ISR to some main code (lower half or kernel thread), it might be convinient to use delayed task switches, and to do the task switches as the last ISR exists. Then you need most of the code I posted above anyway.
The thing is that the requirement to keep ISRs short leads to offloading things from the ISR to mainline code, which will require some kind of locking of the scheduler, and some kind of IRQ-status / delayed scheduling.
Re: Software task switch - interrupted ISR
Because inc/dec don't update flags.Nable wrote:> jnc isr_leave
Did you mean jnz?
Also, I don't remember exactly, but add/sub instr-s don't have implicit lock. Why not inc/dec?
Also, for an SMP-approach, the code need to be revised. The scheduler lock should be per CPU, not per system, so there is a need to find the address of the current CPU, and then do the add/sub within that memory block. There is no need for multiporocessor locks in my implementation as the scheduler lock is per CPU, and is never accessed by other CPUs. Other implementations might need the lock.
But if you want that data to be promptly handled, you need to activate the lower half, kernel thread or handler procedure, which needs to involve the scheduler. You just can't iret back to the original thread that might do some low-priority stuff unrelated to the IRQ.Nable wrote:Ontopic: afaik, people avoid doing heavy things in hardware interrupts' handlers. Handler just adds some data to irq data queue and exits. So, you don't have to think about nested interrupts and possibility to miss some of them.
Last edited by rdos on Mon Jun 04, 2012 3:52 am, edited 1 time in total.