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