Re: A questionable piece of code for context switching (very short, only 5 lines)




"climber.cui" <spamtrap@xxxxxxxxxx> wrote in message
news:1184643963.290379.73880@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
On Jul 16, 3:59 pm, Bjarni Juliusson <spamt...@xxxxxxxxxx> wrote:
climber.cui wrote:
The second thread argument is supposed to start running upon the
function return.

Well, I think you just answered your question yourself then...

When thread A calls SWITCH, the return address of that call is saved in
the state struct of thread A. Then a previously saved return address
from thread B is put instead on the stack, the state of thread B is
loaded into the registers, and SWITCH returns to where it was last
called from thread B. When B calls SWITCH, its return address is saved,
and SWITCH returns to where it was called from A before, and so on.
Where's the problem?

Bjarni
--

hmm. I understand what the program is trying to do. It is just the
last couple of lines really confused me:
..... # loading register values for thread B
1 movl _ESP(%eax),%esp
# restore stack pointer
2 movl _PC(%eax),%eax
# restore return address into eax
3 movl %eax,4(%esp)
# copy over the ret address on the stack ?! why?
4 movl _eax_save,%eax
5 ret
# end of SWITCH
Line 2: move the saved Return address of Thread B to eax.
Line 3: move that saved return address to the stack, but the location
is the memory slot below the stack top, right? that means it just
overwrite the content saved at that location. And then, when 'ret'
instruction is reached, the stack top is poped(let's say the poped
value is x), and the program resumes execution at address x. This
makes no sense, bacause the return address of B is not poped, rather,
it is still on the stack. I would like to replace this line(line 3)
by "pushl %eax", so that the return address is placed at the top of
the stack, and upon execution of 'ret', this return address is poped
in to %eip. In this way, the original stack is not modified, and more
importantly, thread B starts execution at its saved return address.

Either I am wrong or the author was wrong. How do think about it?
thanks.


My guess is that another routine is being returned to. I.e., there is
another return address on the stack.

There seem to be a few versions of NachOS, and perhaps a couple OSes by that
name. But, from the one I was looking at, it appears that it is an
"educational" OS - so, first, I'm not confident the code is correct... But,
what I saw from the code was that a task is interrupted and an interrupt
handler begins execution. The interrupt handler eventually calls SWITCH
with saves the interrupted task ('x'), and sets up another task to be called
('B'). Then SWITCH returns to 'x' (not 'B'), which runs until it calls
"currentThread->Yield()". Then, currentThread->Yield() causes the 'B'
thread to be called. Of course, if I'm correct (I might not be - I only
looked at it for a few minutes and I don't code C++...), that means that
when 'x' resumes it will return to it's interrupted location, not the
location of "currentThread->Yield()". So, some of the code in 'x' is
actually being executed twice... I.e., the code between the interrupted
location and "currentThread->Yield()". If the thread is small, this doesn't
matter much. But, if the thread is large, executing code twice is a waste
of CPU time. However, it appears that some part of the interrupt routine
also calls "currentThread->Yield()" at predetermined intervals. This is
probably to cause a switch to occur for larger threads without executing the
thread far beyond the interrupt location, i.e., less waste of CPU time.
Also, I didn't see any mention of an 'iret', or code to pop cs, or code to
correct the stack pointer when returning from an x86 interrupt. It might be
there, but I just didn't see it. If it's not there, there could be a stack
leak.


Rod Pemberton

.



Relevant Pages

  • Re: cooperative multitasking scheme
    ... >>blocked task is waiting for or an interrupt service routine satisfies ... able to switch tasks between any two instructions i.e. requires a task ... an other task can not pre-empt an other ... the per task stack, so there is no need to save and restore them. ...
    (comp.arch.embedded)
  • Re: cooperative multitasking scheme
    ... >able to switch tasks between any two instructions i.e. requires a task ... and process state than I can in the case of a hardware interrupt that does the ... away is "cooperation" in my use of the term. ... >the per task stack, so there is no need to save and restore them. ...
    (comp.arch.embedded)
  • Re: Lets open source VMS!
    ... Kernel? ... You started this comment thread when I said that of course you need to set the correct stack pointer as a part of a switch to another mode. ... " And do it in an interrupt safe manner. ...
    (comp.os.vms)
  • Re: crash in entry.S restore_all, 2.6.12-rc2, x86, PAGEALLOC
    ... >> IIRC if the interrupt doesn't do the CPL ... >> switch, ... that requires that the kernel stack ... esp had the same pattern: ...
    (Linux-Kernel)
  • Documentation for Multitasking Mouse Draw Demo
    ... This multitasking demo uses an AppleMouse card as a source of interrupts to ... the 6502 hardware stack devoted exclusively to them. ... All changes to the interrupt flag are done "by the book," that is, by using ... A process can also choose to give up its CPU time by calling the YIELD ...
    (comp.sys.apple2.programmer)