This is the mail archive of the ecos-discuss@sourceware.cygnus.com mailing list for the eCos project. See the eCos home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: [ECOS] Preemptive Scheduling in Multilevel Queue Scheduler



gorlick@aero.org (Michael Gorlick) writes:

x> Will someone please straighten me out? After staring at the eCos source code
x> it just isn't clear to me how preemptive (timesliced) scheduling actually
x> works in
x> the multilevel queue scheduler (mlqueue).
x> 
x> The expiration of a timeslice results in a DSR being posted on the DSR
x> queue and that
x> DSR, when executed, forces the current thread to relinquish the processor
x> (by invoking
x> "yield()" on the current thread).  However (and this is where my confusion
x> arises) DSRs
x> are executed when, and only when, the scheduler lock is about to transition
x> from 1
x> to 0.  Consequently, if a thread running under the multilevel queue
x> discipline NEVER
x> directly or indirectly invokes the scheduler "unlock()" method  no DSRs
x> will ever be
x> executed and the thread will never be forced to yield the processor
x> irrespective of the
x> number of timeslices periods that have passed.  Is this correct and if not
x> where should
x> I look in the source code to correct my misunderstanding?
x> 
x> The same problem exists for DSRs in general since "unlock_inner" is the only
x> component (as far as I can determine) that calls and executes the posted DSRs.
x> Again, how do device drivers and interrupts get their DSRs executed in a
x> timely manner
x> if their execution can be delayed indefinitely by a thread that, for
x> whatever reason,
x> never acquires or releases the scheduler lock?
x> 
x> Thank you in advance for taking the time to answer my question.
x> 
x> 
x>        __
x>      _/mg\__
x> ... /o-----o>
x> 
x> 

The missing piece of the puzzle is that the scheduler lock is acquired
and released during interrupt processing. In the default interrupt VSR
(in vectors.S) the lock in incremented and in interrupt_end() (in
intr/intr.cxx) as well as posting a DSR, a call to
Cyg_Scheduler::unlock() is made. If the current thread already had the
scheduler locked then nothing happens until it unlocks for the last
time. If the current thread did not have the lock then this call will
cause any DSRs to be run immediately and any rescheduling to take
place. The lock also works here as an interrupt nest counter, so that
rescheduling only occurs when the last nested interrupt exits.

So, in the common case, when interrupting code that does not have the
lock, DSRs are run immediately and any preemption happens right
after. When the current thread has the lock, all of this is deferred
until it releases the lock, which is what the lock is for.

Hope this helps.

-- 
Nick Garnett           mailto:nickg@cygnus.co.uk
Cygnus Solutions, UK   http://www.cygnus.co.uk