[gst-devel] Decoupled elements and schedulers

Martin Soto soto at informatik.uni-kl.de
Tue Mar 30 09:19:03 CEST 2004


On Tue, 2004-03-30 at 17:13, Benjamin Otte wrote: 
> Please commit it when you feel it's ready, since it ceartainly won't break
> anything.
> I committed mine after it worked with Rhythmbox and gst-player.

Ok, I'll commit at some point this week. We need to sort out the issue
with the GstBin patch, though, but I think we'll find at least an
interim solution.

> I certainly want to have the possibility to use different schedulers for
> different parts of a pipeline. That's the reason to have different
> schedulers in the first place. Different schedulers are supposed to have
> different strengths and tradeoffs for speed/feature-completeness and so
> on.

Yeah, I also think it is ok to be able to mix schedulers. We'll see if
we manage to do it.

> R1: Control can be transfered only to functions belonging to elements
>     that are in the PLAYING state.
> R2: If the element is not decoupled only one of all schedulable functions
>     belonging to an element may run at once. This function must have
>     finished running before another function may be called.

Formulated in this way, I find this rule somewhat difficult to accept.
What this would imply in practice is that you'll have a maximum of one
cothread per (non-decoupled) element, since if you had more than one
they would exclude each other anyway. For an element having only chain
and get functions, I can imagine how I would do it, because it'd be just
a matter of performing some sort of internal select operation on all
affected pads and then running the corresponding function.

On the other hand, if you have a loop function together with some
chains/gets, things get ugly, because you never know if you'd rather
schedule the loop, or perform a select on the pads in order to schedule
one chain/get.

I see two ways out of this. Either you forbid an element with a loop to
also have chains and gets, or, at least, you make clear that the chains
and gets won't be run if there's a loop. Or, you provide some mechanism
of mutual exclusion between cothreads, like semaphores or whatever.
Implementing semaphores in the fair scheduler would be trivial, but
other schedulers may have trouble, plus we would have to define an API
for the whole thing.

The first is simple and pretty reasonable, specially if you have a
properly implemented select operation that can be used by the loop
function (fair will have one soon). The second options seems overkill to
me, but is an option nonetheless.

> R3: If the element is decoupled, the same rules as R2 apply per pad, not
>     per element. You may not call loop functions for decoupled elements.

Decoupled elements must manage cothread exclusion in one way or another.
Its ok with me if this is not a problem of the scheduler.

> R4: Loop functions are eligible at anytime.
> R5: Chain functions can only be scheduled if the scheduler can provide
>     them with an input block.
> R6: Get functions can on only be scheduled if the scheduler can provide
>     at least temporary space to store the returned data.
> 
> The execution of a function can be suspended [at least?] in the
> following cases:
> 
> R7: If the function explicitly performs a yield operation, the scheduler
>     is free to suspend its execution and give control to other functions.
> R8: If the function performs a push, pull, select or clock wait
>     operation, the scheduler is free to suspend its execution and give
>     control to other functions.
> R9: If the function performs a block, the scheduler must interrupt
>     scheduling this element (or pad in the decoupled case) until an
>     unblock happened.

Question: isn't that the purpose of those funny lock and unlock
scheduler operations? I saw you implemented them with something like

g_warning ("What's this?");

and I did something similar :-)

> I'll come to R2 and R3 below. R9 is a future extension that should allow
> elements to transfer control to the scheduler instead of interrupting
> control flow. The best example for this is the queue. Instead of calling
> gst_cond_wait when the queue is full and waiting for the other pad to do a
> g_cond_signal, I intend the queue to do a gst_scheduler_block. The other
> side of the queue would then of course do a gst_scheduler_unblock which
> would allow rescheduling the element.

This sounds useful. Question is, if you're going to do that anyway,
shouldn't we have a more general mechanism anyway? One thing I have
thought of is a general event mechanism. Elements could use that for
things like asynchronously waiting for data to be available from a file
descriptor. I wonder if GLib's main loop can help us in that regard.

> The way I see it is this:
> For normal (that is non-decoupled) elements, you basically schedule the
> element. This means only one schedulable function is running per element
> and everything a function belonging to the element does happens for the
> whole element. This also means that if you have 3 sinkpads, each with
> their own chainfunction, if one performs a wait, you may not schedule the
> other three chainfunctions in the meantime. The pads are coupled.
> In the decoupled case, the element is just a container of pads that can
> all be scheduled independantly - they are decoupled. 

Your description is absolutely right. One point remains, though: how do
you know it is time to schedule the pads of a decoupled element? Some
schedulers may need to be reported when the decoupled element changes
its state, in order to prepare for scheduling. Mine, for example, does.
I have a queue of cothreads waiting for processor time, and I only know
I have to put certain threads in the queue because I know the element
changed its state.

> This means every
> action a function does (a wait or a block) is only relevant for that pad.
> This somehow means (at least for me) that no scheduler can be in control
> of the element itself. We have to at least make sure a scheduler in
> control of the element is not in control of the links of this element.
> (It might work if we changed the behaviour in that patch so that
> decoupled elements don't do unsetting the scheduler on links from the
> decoupled element, now that I think about it. Would that work for you?)

Yes, I guess that'd work for me. Would be a good temporary solution at
least.

> The theory says elements should not do that. If some elements must do that
> we need to invent a way for them to allow that. I don't think any element
> does that though, they all use pointers from their element struct. (If
> they clean them up correctly when going back to READY or being destroyed,
> now that's another question.)

Agreed. Elements can avoid problems in that respect by just keeping
stuff in the object structure.

M. S.
-- 
Martin Soto <soto at informatik.uni-kl.de>





More information about the gstreamer-devel mailing list