NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/39204
The following reply was made to PR kern/39204; it has been noted by GNATS.
From: Nat Sloss <nathanialsloss%yahoo.com.au@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/39204
Date: Mon, 14 May 2012 22:26:11 +1000
Hi.
Thank you for the guidelines. I'm still learning. I'm more of a hack than a
programmer though :)
I hope this is better:
===================================================================
RCS file: /cvsroot/src/sys/dev/pad/pad.c,v
retrieving revision 1.19
diff -u -r1.19 pad.c
--- pad/pad.c 24 Nov 2011 01:54:08 -0000 1.19
+++ pad/pad.c 14 May 2012 12:20:17 -0000
@@ -374,11 +374,6 @@
intrarg = sc->sc_intrarg;
}
- if (intr) {
- mutex_enter(&sc->sc_intr_lock);
- (*intr)(intrarg);
- mutex_exit(&sc->sc_intr_lock);
- }
mutex_exit(&sc->sc_lock);
return
err;===================================================================
RCS file: /cvsroot/src/sys/dev/audio.c,v
retrieving revision 1.261
diff -u -r1.261 audio.c
--- audio.c 30 Apr 2012 02:16:46 -0000 1.261
+++ audio.c 14 May 2012 12:21:06 -0000
@@ -401,6 +401,7 @@
cv_init(&sc->sc_rchan, "audiord");
cv_init(&sc->sc_wchan, "audiowr");
cv_init(&sc->sc_lchan, "audiolk");
+ cv_init(&sc->sc_dataready, "audiordy");
if (hwp == 0 || hwp->get_locks == 0) {
printf(": missing method\n");
@@ -760,6 +761,7 @@
cv_destroy(&sc->sc_rchan);
cv_destroy(&sc->sc_wchan);
cv_destroy(&sc->sc_lchan);
+ cv_destroy(&sc->sc_dataready);
return 0;
}
@@ -2211,12 +2213,15 @@
sc, uio->uio_resid,
audio_stream_get_used(sc->sc_pustream),
sc->sc_pr.usedhigh));
cb = &sc->sc_pr;
- if (cb->mmapped)
- return EINVAL;
+ if (cb->mmapped) {
+ error = EINVAL;
+ goto audio_write_end;
+ }
if (uio->uio_resid == 0) {
sc->sc_eof++;
- return 0;
+ error = 0;
+ goto audio_write_end;
}
#ifdef AUDIO_PM_IDLE
@@ -2232,7 +2237,8 @@
uio->uio_offset += uio->uio_resid;
uio->uio_resid = 0;
DPRINTF(("audio_write: half-dpx read busy\n"));
- return 0;
+ error = 0;
+ goto audio_write_end;
}
if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
@@ -2241,8 +2247,10 @@
uio->uio_offset += n;
uio->uio_resid -= n;
sc->sc_playdrop -= n;
- if (uio->uio_resid == 0)
- return 0;
+ if (uio->uio_resid == 0) {
+ error = 0;
+ goto audio_write_end;
+ }
}
/**
@@ -2265,13 +2273,15 @@
"hiwat=%d\n", used,
cb->usedlow, cb->usedhigh));
mutex_exit(sc->sc_intr_lock);
- if (ioflag & IO_NDELAY)
- return EWOULDBLOCK;
+ if (ioflag & IO_NDELAY) {
+ error = EWOULDBLOCK;
+ goto audio_write_end;
+ }
error = audio_waitio(sc, &sc->sc_wchan);
if (sc->sc_dying)
error = EIO;
if (error)
- return error;
+ goto audio_write_end;
mutex_enter(sc->sc_intr_lock);
}
inp = cb->s.inp;
@@ -2298,6 +2308,7 @@
cc = stream.end - stream.start;
error = fetcher->fetch_to(sc, fetcher, &stream, cc);
}
+
mutex_enter(sc->sc_intr_lock);
if (sc->sc_npfilters > 0) {
cb->fstamp += ufetcher.last_used
@@ -2343,6 +2354,8 @@
}
mutex_exit(sc->sc_intr_lock);
+audio_write_end:
+ cv_broadcast(&sc->sc_dataready);
return error;
}
@@ -2791,7 +2804,8 @@
if (!audio_can_playback(sc))
return EINVAL;
- if (!sc->sc_pr.mmapped && used < sc->sc_pr.blksize) {
+ if (!sc->sc_pr.mmapped && used < sc->sc_pr.blksize &&
+ sc->hw_if->trigger_output != NULL) {
cv_broadcast(&sc->sc_wchan);
DPRINTF(("%s: wakeup and return\n", __func__));
return 0;
@@ -2928,6 +2942,7 @@
int cc, used;
int blksize;
int error;
+ int i, timeout;
sc = v;
@@ -3042,8 +3057,28 @@
sc->sc_mode, cb->pause,
audio_stream_get_used(sc->sc_pustream), cb->usedlow));
if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) {
- if (audio_stream_get_used(sc->sc_pustream) <= cb->usedlow)
+ if ((used = audio_stream_get_used(sc->sc_pustream)) <=
cb->usedlow)
softint_schedule(sc->sc_sih_wr);
+
+ if (used < blksize && device_is_a(sc->sc_dev, "pad")) {
+ i = 0;
+ timeout = mstohz(5);
+ if (timeout == 0)
+ timeout = 1;
+
+ mutex_exit(sc->sc_intr_lock);
+ while ((used = audio_stream_get_used(sc->sc_pustream))
+ < blksize && cb->usedlow > blksize) {
+ softint_schedule(sc->sc_sih_wr);
+ error = cv_timedwait_sig(&sc->sc_dataready,
sc->sc_lock, timeout);
+ i++;
+ if (error != 0 && error != EWOULDBLOCK)
+ break;
+ if (i > 200)
+ break;
+ }
+ mutex_enter(sc->sc_intr_lock);
+ }
}
/* Possible to return one or more "phantom blocks" now. */
===================================================================
RCS file: /cvsroot/src/sys/dev/audiovar.h,v
retrieving revision 1.46
diff -u -r1.46 audiovar.h
--- audiovar.h 23 Nov 2011 23:07:31 -0000 1.46
+++ audiovar.h 14 May 2012 12:23:06 -0000
@@ -147,6 +147,7 @@
kcondvar_t sc_rchan;
kcondvar_t sc_wchan;
kcondvar_t sc_lchan;
+ kcondvar_t sc_dataready;
int sc_dvlock;
bool sc_dying;
I tested this with the scenarios mentioned before and it works even better
than my first attempt :)
Note: This patch is my own work which I submit under the NetBSD license.
I hope this helps and thanks for the feedback. May my future patches be even
better.
Regards,
Nat.
Home |
Main Index |
Thread Index |
Old Index