On 2010-02-06, Bart Veer <ba...@ecoscentric.com> wrote: >>>>>> "Grant" == Grant Edwards <grant.b.edwa...@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