[pulseaudio-discuss] Vacuuming per-client mempools (was: [PATCH v2 02/12] pulsecore: srbchannel: Introduce per-client SHM files)

Tanu Kaskinen tanuk at iki.fi
Fri Feb 12 11:03:39 UTC 2016


On Fri, 2016-02-12 at 08:08 +0200, Ahmed S. Darwish wrote:
> On Fri, Feb 12, 2016 at 02:09:31AM +0200, Ahmed S. Darwish wrote:
> > The PA daemon currently uses a single SHM file for all the clients
> > sending and receiving commands over the low-latency srbchannel
> > mechanism.
> > 
> > To safely run PA daemon in system mode later using memfds, and to
> > provide the necessary ground work for sandboxing, create the
> > srbchannel SHM files on a per-client basis.
> > 
> ...
> > @@ -285,8 +278,16 @@ void pa_core_maybe_vacuum(pa_core *c) {
> >  
> >      pa_mempool_vacuum(c->mempool);
> >  
> > -    if (c->rw_mempool)
> > -        pa_mempool_vacuum(c->rw_mempool);
> > +    /*
> > +     * FIXME: Vacuum the per-client rw (srbchannel) mempools
> > +     *
> > +     * We need to vacuum the per-client mempool owned by each connection
> > +     * at pa_native_protocol::connections. Nonetheless, libpulsecore can
> > +     * not access any symbol from protocol-native.
> > +     *
> > +     * Vacuuming a per-client mempool on its streams deletion and
> > +     * uncorking also proved to be problematic.
> > +     */
> >  }
> > 
> 
> During patch review of v1 submission, a consensus was reached to
> vacuum the per-client mempool according to streams activity. [*]
> 
> So the logic goes:
> 
> - Upon corking a stream, if there are no more 'active' streams, let's
>   vacuum per-client mempool
> 
> - Upon deleting a stream, if all the remaining streams are not active
>   (corked) or no more streams left, vacuum
> 
> - Upon finishing an upload stream, if no other streams remain or all
>   are inactive, vacuum
> 
> When implementing this seemingly-innocent logic, I've found that we
> are vacuuming way too much. 
> 
> Here's a case-by-case analysis:
> 
> #####################################################################
> 
> 1) GNOME music, official gnome3 music application
>    https://wiki.gnome.org/Apps/Music
> 
>    After starting application, _clicking_ a song to play we get:
> 
>        CREATING/CONNECTING stream with name = pulsesink probe
>        DELETING stream with name = pulsesink probe
>        <----------------- VACUUM ------------------->
>        CREATING/CONNECTING stream with name = Playback Stream
>        UN_CORKING stream with name = Playback Stream
>    
>    Whenever the app _transitions_ from song to song, we get:
> 
>        CORKING stream with name = Playback Stream
>        <----------------- VACUUM ------------------->
>        CORKING stream with name = Playback Stream       
>        DELETING stream with name = Playback Stream
>   
> 
>        CREATING/CONNECTING stream with name = pulsesink probe
>        DELETING stream with name = pulsesink probe
>        <----------------- VACUUM ------------------->
>        CREATING/CONNECTING stream with name = Playback Stream
>        UN-CORKING stream with name = Playback Stream
> 
>    When _seeking_ a playing song, we get:
> 
>        CORKING stream with name = Playback Stream
>        <----------------- VACUUM ------------------->
>        UN-CORKING stream with name = Playback Stream
> 
>    FINAL RESULT:
>        2 vacuums per song transition
>        1 vacuum per song seek
>        
> #####################################################################
> 
> 2) Audacious, XMMS successor, http://audacious-media-player.org/
>    Audacious uses ALSA output by default.
> 
>    After starting application, clicking a song to play we get
> 
>        CREATING/CONNECTING stream with name = ALSA Playback
>        DELETING stream with name = ALSA Playback
>        <----------------- VACUUM ------------------->
>        CREATING/CONNECTING stream with name = ALSA Playback
>        UN-CORKING stream with name = ALSA Playback
> 
>    Whenever the app transitions from song to song, we get:
> 
>        CORKING stream with name = ALSA Playback
>        <----------------- VACUUM ------------------->
>        DELETING stream with name = ALSA Playback
>        CREATING/CONNECTING stream with name = ALSA Playback
>        UN-CORKING stream with name = ALSA Playback
> 
>    When seeking a playing song, we get:
> 
>        CORKING stream with name = ALSA Playback
>        <----------------- VACUUM ------------------->
>        DELETING stream with name = ALSA Playback
>        CREATING/CONNECTING stream with name = ALSA Playback
>        UN-CORKING stream with name = ALSA Playback
> 
>    FINAL RESULT:
>        1 vacuum per song transition
>        1 vacuum per song seek
> 
> #####################################################################
> 
> So unfortunately it seems this approach will produce a vacuuming
> overkill and possibly hurt our performance.

Have you checked how much time the vacuuming takes? I'm not sure the
frequent vacuuming is a real problem.

> The original logic depended on the core.c to detect that all sources
> and sinks are idle, and if so, vacuum all the server mempools. Trying
> to maintain this logic faces the issue of libpulsecore not being
> able to access any symbol from protocol-native.

If there's only one application playing (which is the common case), is
there any difference in behaviour with the old code compared to the
new? If there's just one stream, corking/deleting will still cause
vacuuming also with the old code, right?

> So what is the best way to handle this issue?

If it needs handling, I guess we could add a timer that triggers
vacuuming only if the client is still idle after a second or so.

-- 
Tanu


More information about the pulseaudio-discuss mailing list