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]
Other format: [Raw text]

Re: RE: question about starting point of thread context switching(sparc target)? Thanks


"Qiang Huang" <jameshq@liverpool.ac.uk> writes:

> Hi all, Nick:
>    Thanks a lot for your help on this question. but I still have a little
> question abou it:

[snip questions]

You seem to be making very heavy weather of understanding any of
this. One problem seem to be that you are trying to understand too
much all at once. You need to break it down into manageable pieces
which can be understood in isolation and then build those back up into
a bigger picture.


Let me give you a start and try and explain the thread preemption
mechanism to you again.


First consider a voluntary preemption, where a thread calls a kernel
function which will scheduled a higher priority thread -- say
posting to a semaphore.

The thread calls Cyg_Counting_Semaphore::post() which increments the
scheduler lock (from 0 to 1) and inspects the state of the
semaphore. It increments the semaphore's count and inspects the thread
queue. If there is a waiting thread it dequeues it a wakes it up.

Waking the thread consists of putting it back on the scheduler run
queue. If the scheduler detects that this is a higher priority thread
than the current one, it sets the need_reschedule flag.

Cyg_Counting_Semaphore::post() now decrements the scheduler lock and,
since this will zero it, calls unlock_inner(). unlock_inner() sees
that the need_reschedule flag is set and calls the scheduler to get
the highest priority thread available. If this is not the current
thread then it context switches to the new thread.

When the new thread eventually sleeps, a context switch will bring us
back to unlock_inner() in the first thread where it will zero the
scheduler lock and return to post(), which will then return to its
caller.


Now consider an involuntary preemption as a result of an interrupt.

The interrupt VSR saves CPU state on the thread stack, increments the
scheduler lock, and calls the ISR. When the ISR returns the VSR calls
interrupt_end().  interrupt_end() looks at the ISR's return value and
posts the DSR.

interrupt_end() now decrements the the scheduler lock and since this
will zero it calls unlock_inner(). unlock_inner() checks for any
pending DSRs and calls these.

Lets say that the DSR posted by the ISR posts a semaphore. It executes
exactly the same code as described above except that since the
scheduler lock was already non-zero the call to unlock_inner() is not
made and post() just drop back out to the DSR and eventually to
unlock_inner().

If the semaphore post operation caused a new higher priority thread to
be scheduled then unlock_inner() will see the need_reschedule flag and
will context switch to the new thread.

When the new thread eventually sleeps, a context switch will bring us
back to unlock_inner() in the interrupted thread which will zero the
scheduler lock and return to interrupt_end(). This then returns to the
interrupt VSR which then resumes the interrupted code by pulling its
state off its stack.


So, involuntary preemption works in exactly the same way as voluntary
preemption. We just arrange for the interrupted thread to call
unlock_inner(). It is then totally irrelevant to the scheduler and
context switch code whether the current thread has been interrupted or
not.

I hope this helps to make things clearer.

-- 
Nick Garnett - eCos Kernel Architect
http://www.eCosCentric.com/

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


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