From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Garnett To: ecos-discuss@cygnus.com Subject: Re: [ECOS] Preemptive Scheduling in Multilevel Queue Scheduler Date: Fri, 11 Dec 1998 06:51:00 -0000 Message-id: References: X-SW-Source: 1998/msg00088.html 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