This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: context switching in ecos



Suet Fei Li <suetfei@bwrc.eecs.berkeley.edu> writes:
> I am trying to understand the context switching stuff in Ecos here.  It
> seems like it goes the following way:
> 
> timer interrupt -> save everything on the current thread stack -> call ISR
> -> Interrupt_end -> call DSR -> lock scheduler -> call
> HAL_THREAD_SWITCH_CONTEXT  -> save current context and load next thread
> context -> return from interrupt -> restore everything.
> 
> It seems to me that the current status of the CPU has to be saved twice
> (once right after the interrupt, the second time during
> HAL_THREAD_SWITCH_CONTEXT ).

To amplify what Nick said slightly...

But consider: a voluntary call to deschedule (like sleep() or a wait()
call) is a function call - the caller will have saved their registers
already.  Only (a subset of) callee-save registers need to be saved.  With
some procedure call standards, a voluntary deschedule needs to save almost
nothing except the stack pointer.

Further, an interrupt must save a few registers away *right now*, in order
to get workspace to handle the interrupt.  But next it makes a standard
sort of function call - which saves callee-save registers.  So the initial
"right-now" save doesn't need to save them all.

So if a thread stopped 'cos of a call into the scheduler, a few registers
are saved in the threadstate, and the rest of what's required is saved in
the call stack frame created when the task made that function call.

If a thread stopped 'cos of an interrupt, a few regs are saved in the stack
in a special interrupt-type stack context, the rest are saved in the stack
in a procedure-call related frame.  That's where the interrupted context
lives, entirely.  BUT there is a further set saved from the call into the
scheduler - that makes sure than when this thread restarts, it runs the
finish of the interrupt handler and restores the interrupted context from
the special interrupt-type stack context.  So the saved context in the
thread state is like a pointer to code that will get the real context off
the stack.

The point of all this is: the code to restart a thread does not need to
know whether it volunteered to deschedule, or it was interrupted.  The
contexts are handled the same way.  One takes you to your synchronous
function call with lots of state on the stack, the other takes you to the
end of the interrupt handler, which will return-from-interrupt using
whatever CPU-specific magic is needed.

> If this is indeed true, isn't it rather
> inefficient? Why did not it just:
> 
> interrupt -> save everything on the current thread -> scheduler -> load the
> context from next thread.

Because that sequence is really:

 interrupt -> save everything on the current thread -> save some registers
 again on stack in function call -> scheduler -> load the context from
 next thread -> restore some regs again from stack in function return

which is inefficient.  
And when it doesn't reschedule at all, the sequence

 interrupt -> save everything on the current thread -> save some registers
 again on stack in function call -> scheduler -> load the context from
 *SAME* thread -> restore some regs again from stack in function return

is very very inefficient! ;-)

	- Huge

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]