[ECOS] Preemptive Scheduling in Multilevel Queue Scheduler

Bart Veer bartv@cygnus.co.uk
Fri Dec 11 06:51:00 GMT 1998

>>>>> "Michael" == Michael Gorlick <gorlick@aero.org> writes:

    Michael> Will someone please straighten me out? After staring at
    Michael> the eCos source code it just isn't clear to me how
    Michael> preemptive (timesliced) scheduling actually works in the
    Michael> multilevel queue scheduler (mlqueue).

    Michael> The expiration of a timeslice results in a DSR being
    Michael> posted on the DSR queue and that DSR, when executed,
    Michael> forces the current thread to relinquish the processor (by
    Michael> invoking "yield()" on the current thread). However (and
    Michael> this is where my confusion arises) DSRs are executed
    Michael> when, and only when, the scheduler lock is about to
    Michael> transition from 1 to 0. Consequently, if a thread running
    Michael> under the multilevel queue discipline NEVER directly or
    Michael> indirectly invokes the scheduler "unlock()" method no
    Michael> DSRs will ever be executed and the thread will never be
    Michael> forced to yield the processor irrespective of the number
    Michael> of timeslices periods that have passed. Is this correct
    Michael> and if not where should I look in the source code to
    Michael> correct my misunderstanding?

    Michael> The same problem exists for DSRs in general since
    Michael> "unlock_inner" is the only component (as far as I can
    Michael> determine) that calls and executes the posted DSRs.
    Michael> Again, how do device drivers and interrupts get their
    Michael> DSRs executed in a timely manner if their execution can
    Michael> be delayed indefinitely by a thread that, for whatever
    Michael> reason, never acquires or releases the scheduler lock?

The missing piece in the puzzle is the routine interrupt_end() in
kernel/v1.1/src/intr/intr.cxx. This gets invoked at the end of ISR
interrupt handling, and includes a call to Cyg_Scheduler::unlock().

If an interrupt happens when the foreground application was executing
ordinary code, and a resulting DSR has invoked yield(), this call to
unlock() will result in a context switch at the end of interrupt
handling. If the foreground application was in a critical section at
the time that the interrupt occurred then the scheduler will be
locked, the interrupt handler will return to the current thread, and
the context switch happens when the thread leaves its critical section
and unlocks the scheduler.

Bart Veer // eCos net maintainer

More information about the Ecos-discuss mailing list