Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Simplify locking. Hold intr lock only when dealing ...



details:   https://anonhg.NetBSD.org/src/rev/b715a5b9be7c
branches:  trunk
changeset: 351737:b715a5b9be7c
user:      nat <nat%NetBSD.org@localhost>
date:      Fri Feb 24 09:49:49 2017 +0000

description:
Simplify locking.  Hold intr lock only when dealing with sc_pr (mix ring)
or virtual channel 0 (hardware).

diffstat:

 sys/dev/audio.c |  78 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 40 insertions(+), 38 deletions(-)

diffs (truncated from 403 to 300 lines):

diff -r 56d11a49bb33 -r b715a5b9be7c sys/dev/audio.c
--- a/sys/dev/audio.c   Fri Feb 24 07:52:39 2017 +0000
+++ b/sys/dev/audio.c   Fri Feb 24 09:49:49 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.309 2017/02/24 07:52:39 skrll Exp $        */
+/*     $NetBSD: audio.c,v 1.310 2017/02/24 09:49:49 nat Exp $  */
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.309 2017/02/24 07:52:39 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.310 2017/02/24 09:49:49 nat Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -206,6 +206,12 @@
 int    audio_idle_timeout = 30;
 #endif
 
+#define HW_LOCK(x)     if (x == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) \
+                               mutex_enter(sc->sc_intr_lock);
+
+#define HW_UNLOCK(x)   if (x == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) \
+                               mutex_exit(sc->sc_intr_lock);
+
 int    audio_blk_ms = AUDIO_BLK_MS;
 
 int    audiosetinfo(struct audio_softc *, struct audio_info *, bool,
@@ -1280,7 +1286,7 @@
        }
 
        /* Swap in new filters. */
-       mutex_enter(sc->sc_intr_lock);
+       HW_LOCK(vc);
        memcpy(of, vc->sc_pfilters, sizeof(of));
        memcpy(os, vc->sc_pstreams, sizeof(os));
        onfilters = vc->sc_npfilters;
@@ -1298,7 +1304,7 @@
                vc->sc_mpr.s.param = pfilters->filters[0].param;
                vc->sc_pustream = &vc->sc_pstreams[0];
        }
-       mutex_exit(sc->sc_intr_lock);
+       HW_UNLOCK(vc);
 
        /* Destroy old filters. */
        for (i = 0; i < onfilters; i++) {
@@ -1365,7 +1371,7 @@
        }
 
        /* Swap in new filters. */
-       mutex_enter(sc->sc_intr_lock);
+       HW_LOCK(vc);
        memcpy(of, vc->sc_rfilters, sizeof(of));
        memcpy(os, vc->sc_rstreams, sizeof(os));
        onfilters = vc->sc_nrfilters;
@@ -1383,7 +1389,7 @@
                vc->sc_mrr.s.param = rfilters->filters[0].param;
                vc->sc_rustream = &vc->sc_rstreams[rfilters->req_size - 1];
        }
-       mutex_exit(sc->sc_intr_lock);
+       HW_UNLOCK(vc);
 
 #ifdef AUDIO_DEBUG
        printf("%s: HW-buffer=%p pustream=%p\n",
@@ -2187,7 +2193,6 @@
        DPRINTF(("audio_open: done sc_mode = 0x%x\n", vc->sc_mode));
 
        grow_mixer_states(sc, 2);
-       mutex_enter(sc->sc_intr_lock);
        if (flags & FREAD)
                sc->sc_recopens++;
        sc->sc_opens++;
@@ -2195,7 +2200,6 @@
        chan->chan = n;
        chan->deschan = n;
        SIMPLEQ_INSERT_TAIL(&sc->sc_audiochan, chan, entries);
-       mutex_exit(sc->sc_intr_lock);
 
        error = fd_clone(fp, fd, flags, &audio_fileops, chan);
        KASSERT(error == EMOVEFD);
@@ -2303,7 +2307,9 @@
                cc = cb->blksize - (inp - cb->s.start) % cb->blksize;
                audio_fill_silence(&cb->s.param, inp, cc);
                cb->s.inp = audio_stream_add_inp(&cb->s, inp, cc);
+               mutex_exit(sc->sc_intr_lock);
                error = audiostartp(sc, vc);
+               mutex_enter(sc->sc_intr_lock);
                if (error)
                        return error;
        } else if (hw == true) {
@@ -2411,6 +2417,8 @@
 
        if (sc->sc_opens == 1 && hw->close != NULL)
                hw->close(sc->hw_hdl);
+       mutex_exit(sc->sc_intr_lock);
+
        if (sc->sc_opens == 1) {
                sc->sc_async_audio = 0;
                kauth_cred_free(sc->sc_credentials);
@@ -2438,7 +2446,6 @@
        sc->sc_opens--;
        shrink_mixer_states(sc, 2);
        SIMPLEQ_REMOVE(&sc->sc_audiochan, chan, audio_chan, entries);
-       mutex_exit(sc->sc_intr_lock);
        mutex_exit(sc->sc_lock);
        audio_free_ring(sc, &vc->sc_mpr);
        audio_free_ring(sc, &vc->sc_mrr);
@@ -2510,12 +2517,10 @@
                return error;
        }
 
-       mutex_enter(sc->sc_intr_lock);
        while (uio->uio_resid > 0 && !error) {
                while ((used = audio_stream_get_used(vc->sc_rustream)) <= 0) {
                        if (!vc->sc_rbus && !vc->sc_mrr.pause)
                                error = audiostartr(sc, vc);
-                       mutex_exit(sc->sc_intr_lock);
                        if (error)
                                return error;
                        if (ioflag & IO_NDELAY)
@@ -2526,7 +2531,6 @@
                                error = EIO;
                        if (error)
                                return error;
-                       mutex_enter(sc->sc_intr_lock);
                }
 
                outp = vc->sc_rustream->outp;
@@ -2553,7 +2557,6 @@
                        (vc->sc_rustream, outp, n);
                cb->copying = false;
        }
-       mutex_exit(sc->sc_intr_lock);
        return error;
 }
 
@@ -2838,7 +2841,6 @@
        }
 
        error = 0;
-       mutex_enter(sc->sc_intr_lock);
        while (uio->uio_resid > 0 && !error) {
                /* wait if the first buffer is occupied */
                while ((used = audio_stream_get_used(vc->sc_pustream)) >=
@@ -2846,7 +2848,6 @@
                        DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d "
                                     "hiwat=%d\n", used,
                                     cb->usedlow, cb->usedhigh));
-                       mutex_exit(sc->sc_intr_lock);
                        if (ioflag & IO_NDELAY)
                                return EWOULDBLOCK;
                        error = audio_waitio(sc, &sc->sc_wchan, vc);
@@ -2854,7 +2855,6 @@
                                error = EIO;
                        if (error)
                                return error;
-                       mutex_enter(sc->sc_intr_lock);
                }
                inp = cb->s.inp;
                cb->copying = true;
@@ -2862,7 +2862,6 @@
                used = stream.used;
 
                /* Write to the sc_pustream as much as possible. */
-               mutex_exit(sc->sc_intr_lock);
                if (vc->sc_npfilters > 0) {
                        filter = vc->sc_pfilters[0];
                        filter->set_fetcher(filter, &ufetcher.base);
@@ -2881,7 +2880,6 @@
                        cc = stream.end - stream.start;
                        error = fetcher->fetch_to(sc, fetcher, &stream, cc);
                }
-               mutex_enter(sc->sc_intr_lock);
                if (vc->sc_npfilters > 0) {
                        cb->fstamp += ufetcher.last_used
                            - audio_stream_get_used(vc->sc_pustream);
@@ -2924,7 +2922,6 @@
                        audio_fill_silence(&cb->s.param, einp, cc);
                }
        }
-       mutex_exit(sc->sc_intr_lock);
 
        return error;
 }
@@ -2994,12 +2991,12 @@
                        mutex_exit(sc->sc_intr_lock);
                        return error;
                }
+               mutex_exit(sc->sc_intr_lock);
                if ((vc->sc_mode & AUMODE_PLAY) && !vc->sc_pbus && pbus)
                        error = audiostartp(sc, vc);
                if (!error &&
                    (vc->sc_mode & AUMODE_RECORD) && !vc->sc_rbus && rbus)
                        error = audiostartr(sc, vc);
-               mutex_exit(sc->sc_intr_lock);
                break;
 
        /*
@@ -3019,12 +3016,12 @@
         */
        case AUDIO_GETIOFFS:
                ao = (struct audio_offset *)addr;
-               mutex_enter(sc->sc_intr_lock);
+               HW_LOCK(vc);
                /* figure out where next DMA will start */
                stamp = vc->sc_rustream == &vc->sc_mrr.s
                        ? vc->sc_mrr.stamp : vc->sc_mrr.fstamp;
                offs = vc->sc_rustream->inp - vc->sc_rustream->start;
-               mutex_exit(sc->sc_intr_lock);
+               HW_UNLOCK(vc);
                ao->samples = stamp;
                ao->deltablks =
                  (stamp / vc->sc_mrr.blksize) -
@@ -3035,13 +3032,13 @@
 
        case AUDIO_GETOOFFS:
                ao = (struct audio_offset *)addr;
-               mutex_enter(sc->sc_intr_lock);
+               HW_LOCK(vc);
                /* figure out where next DMA will start */
                stamp = vc->sc_pustream == &vc->sc_mpr.s
                        ? vc->sc_mpr.stamp : vc->sc_mpr.fstamp;
                offs = vc->sc_pustream->outp - vc->sc_pustream->start
                        + vc->sc_mpr.blksize;
-               mutex_exit(sc->sc_intr_lock);
+               HW_UNLOCK(vc);
                ao->samples = stamp;
                ao->deltablks =
                  (stamp / vc->sc_mpr.blksize) -
@@ -3153,7 +3150,7 @@
        DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, vc->sc_mode));
 
        revents = 0;
-       mutex_enter(sc->sc_intr_lock);
+       HW_LOCK(vc);
        if (events & (POLLIN | POLLRDNORM)) {
                used = audio_stream_get_used(vc->sc_rustream);
                /*
@@ -3180,7 +3177,7 @@
                    (used <= vc->sc_mpr.usedlow))
                        revents |= events & (POLLOUT | POLLWRNORM);
        }
-       mutex_exit(sc->sc_intr_lock);
+       HW_UNLOCK(vc);
 
        if (revents == 0) {
                if (events & (POLLIN | POLLRDNORM))
@@ -3370,17 +3367,13 @@
                if (cb != &sc->sc_rr) {
                        audio_fill_silence(&cb->s.param, cb->s.start,
                                           cb->s.bufsize);
-                       mutex_enter(sc->sc_intr_lock);
                        vc->sc_pustream = &cb->s;
                        if (!vc->sc_pbus && !vc->sc_mpr.pause)
                                (void)audiostartp(sc, vc);
-                       mutex_exit(sc->sc_intr_lock);
                } else {
-                       mutex_enter(sc->sc_intr_lock);
                        vc->sc_rustream = &cb->s;
                        if (!vc->sc_rbus && !sc->sc_rr.pause)
                                (void)audiostartr(sc, vc);
-                       mutex_exit(sc->sc_intr_lock);
                }
        }
 
@@ -3394,7 +3387,6 @@
 {
 
        KASSERT(mutex_owned(sc->sc_lock));
-       KASSERT(mutex_owned(sc->sc_intr_lock));
 
        DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
                 vc->sc_mrr.s.start, audio_stream_get_used(&vc->sc_mrr.s),
@@ -3404,8 +3396,10 @@
                return EINVAL;
 
        if (sc->sc_rec_started == false) {
+               mutex_enter(sc->sc_intr_lock);
                mix_read(sc);
                cv_broadcast(&sc->sc_rcondvar);
+               mutex_exit(sc->sc_intr_lock);
        }
        vc->sc_rbus = true;
 
@@ -3419,7 +3413,6 @@
        int error, used;
 
        KASSERT(mutex_owned(sc->sc_lock));
-       KASSERT(mutex_owned(sc->sc_intr_lock));
 
        chan = SIMPLEQ_FIRST(&sc->sc_audiochan);
        error = 0;
@@ -3440,15 +3433,17 @@
        vc->sc_pbus = true;
        if (sc->sc_trigger_started == false) {
                audio_mix(sc);
-               mix_write(sc);



Home | Main Index | Thread Index | Old Index