From: orion h. <oh...@bt...> - 2001-04-01 20:02:28
|
Matt Howell wrote: > > erik, brent and i spent some time talking about plans for scheduling re-work > of GStreamer. following are the notes which i'll also check into docs/random. > > take a look and comment / correct. > > matt. > > ps - erik and i hope to get this done within a couple of weeks. > > ----- > > ------------------------------------------------------------------------ > ----------------------------------------------------------- > - GStreamer Scheduling / Synchronization (incsched) Notes - > ----------------------------------------------------------- > > These notes describe deadlock scenarios and proposed solutions for > GStreamer. This will be implemented in the INCSCHED1 branch. > > I. Miscelaneous proposals > II. Deadlock scenarios and propsed solutions > III. State transition approach and responsibility > > MattH. > > -------------------------------- > - I. Miscalenous proposals - > -------------------------------- > > 1. Change the names of GstThread and GstQueue to GstPtThread and GstPtQueue > for pthread versions of Thread and Queue. > > 2. Change GstPtQueue to check its pads' peers' managers and make sure > they are different. If not, fail and generate error message. (This > ensures a GstPtQueue straddles a pthread boundary.) > > 3. Change state transitions to NULL <-> READY <-> PAUSED <-> PLAYING. > > --------------------------------------------------- > - II. Deadlock Scenarios and Proposed Solutions - > - (in the order they will be implemented) - > --------------------------------------------------- > > 1. A downstream element "waits" for a buffer from its upstream element, > a state change happens and "pauses" the upstream element -- the > downstream element is blocked and cannot execute its change_state. > > Note that this can only happen within a single GstPtQueue! Either a > downstream element calls Pull, finds no buffer, and does a > wait_cond(new buffer) or an upstream element calls Push, finds no > room, and does a wait_cond(new room). Thus, GstPtQueue contains all > the cond_wait / signal code. > > => The managing container (thread, pipeline) "wakes" up any sleep > conditions of its "bottom half". (In the scenario described, it > wakes the blocked downstream element's call to Pull.) The GstPtQueue > cond_wait section determines that it woke up due to a pending state > change and does a cothread_switch(0) to return to the main loop, > which then executes the state transition. > > Note that a managing container will have only one sleep condition > in its "bottom half." > > 2. Element "blocked" on getting I/O and cannot execute its change_state. > > => We will provide an I/O library for the elements to use that does > not actually block. (A retry-loop with timeout or select() on > 2 -- or more -- file descriptors: one the one you want I/O from, > the other one that GStreamer uses to "wake" everyone up.) The > I/O library determines that it was woken due to a pending state > change and does a cothread_switch(0) to return to the main loop, > which then executes the state transition. > > Note that a managing container will have only one elements in > the middle of doing blocking I/O. > > 3. Element using a library (code out of its control) which blocks for > some reason (e.g., using real blocking I/O) so main loop never gets > run to execute change_state. > > => Build in some timeout in the manging container (the "top half") > when waiting for bottom half to respond to pending state. If > managing container times out, kill the element's thread with a > signal (or series of signals -- escalating priority). This > requires that the element (the "bottom half") have matching > signal handler(s) that execute(s) the state-transition. Disclaimer: *** I'm not privy to the previous discussions on this, nor am I fully upto speed on gstreamer; just started hacking some plugins this week. *** Another way of dealing with blocking I/O is to put the scheduler of a given bin into a separate thread. All of the elements run their chaining functions within that thread. If a source or sink blocks the elements in the bin block with it, but there's no spinning and no i/o changes on imported modules. A change of state to the elements of the bin just requires cancelling the bin's scheduling thread and invoking the change_state functions of the individual elements. Did this get ruled out already? Kind Regards - Orion |