This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: MLQ scheduler policy question
On 2010-02-06, Bart Veer <bartv@ecoscentric.com> wrote:
>>>>>> "Grant" == Grant Edwards <grant.b.edwards@gmail.com> writes:
>
> Grant> Assume we're using the MLQ scheduler and there are a set of
> Grant> threads all running at the same priority. The eCos docs
> Grant> specify that the running thread won't be pre-empted by
> Grant> another thread of the same priority unless the running
> Grant> thread explicitly yields/blocks.
>
> Grant> What isn't specified is what happens when a higher priority
> Grant> thread becomes runnable, preempts one of our set-of-equals,
> Grant> then blocks. Since the documentation doesn't specify that
> Grant> the original thread will be resumed, I assume the scheduler
> Grant> is free to choose any of the ready threads?
>
> In theory yes, and of course the behaviour may change at any time
> since we have not documented specific behaviour.
That was my conclusion.
> Grant> In practice is there a way to predict which of multiple ready,
> Grant> equal-priority threads will be scheduled? [No, I'm not going
> Grant> to depend on it, but I'm curious.]
>
> IIRC (and it has been a while since I looked at the code), in
> practice a thread will remain at the head of its priority's
> run queue unless it explicitly yields/blocks or gets
> timesliced. Hence when there are no more runnable
> higher-priority threads the preempted thread gets resumed.
That appears to be the behavior we've observered, but I've told
people not to depend on it.
> It may of course get timesliced microseconds later when the
> next clock interrupt occurs, if timeslicing is enabled and its
> slice has expired.
>
> Grant> The real-world case is a thread that calls send() on a TCP
> Grant> socket. Some code was written under the assumption that the
> Grant> thread that called send() would continue to run (after network
> Grant> threads were finished) until it explicitly yeilded or blocked.
That raises another question: is the MLQ shedule queueing
behavior defined in the case when a thread does explicitly
yield? IOW is the yield()ing thread guaranteed to go the back
of queue?
The user manual mentions using cyg_thread_yeild() to implement
cooperative multitasking among a group of equal-priority
threads. For that to work, there needs to be a queue ordering
policy to guarantee something like round-robin scheduling of
threads within the equal-priority group.
Despite my encouragement to come up with a more event-driven
design, somebody I work with has a group of equal-priority
threads that call cyg_thread_yield() and cyg_thread_delay() as
a sort of cooperative multi-tasking scheme. AFAICT, it seems
to work, but it makes me a bit uneasy...
> Grant> I don't think that assumption is valid, and calling send() may
> Grant> cause a context switch (indirectly) to another equal-priority
> Grant> task.
>
> send() is not a primitive kernel call. It needs to synchronize with
> the rest of the TCP/IP stack for access to resources like mbufs. It
> needs to synchronize with the I/O layers and the device driver for
> access to the hardware. Etc.
FWIW based on some scheduler tracing, the main "interruption"
that happens when calling send() is that it usually un-blocks
one/both of the network threads (which are generally higher
priority).
> There is no easy way to predict just what is going to happen
> in terms of context switches, and any code that makes such
> assumptions is not going to be robust.
Thanks for confirming that.
--
Grant Edwards grante Yow! If our behavior is
at strict, we do not need fun!
visi.com
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss