Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pad Allow reads from pad(4) less or greater than PAD...
details: https://anonhg.NetBSD.org/src/rev/0784ce5bea3d
branches: trunk
changeset: 813912:0784ce5bea3d
user: nat <nat%NetBSD.org@localhost>
date: Fri Feb 26 13:17:04 2016 +0000
description:
Allow reads from pad(4) less or greater than PAD_BLKSIZE.
Ensure that audio data is ready before reading.
Addresses PR 39204.
OK jmcneil@.
diffstat:
sys/dev/pad/pad.c | 57 +++++++++++++++++++++++++++++++++++++--------------
sys/dev/pad/padvar.h | 4 ++-
2 files changed, 44 insertions(+), 17 deletions(-)
diffs (146 lines):
diff -r 00e48834a9fa -r 0784ce5bea3d sys/dev/pad/pad.c
--- a/sys/dev/pad/pad.c Fri Feb 26 13:08:28 2016 +0000
+++ b/sys/dev/pad/pad.c Fri Feb 26 13:17:04 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.23 2015/07/10 21:58:56 nat Exp $ */
+/* $NetBSD: pad.c,v 1.24 2016/02/26 13:17:04 nat Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.23 2015/07/10 21:58:56 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.24 2016/02/26 13:17:04 nat Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -43,6 +43,7 @@
#include <sys/vnode.h>
#include <sys/module.h>
#include <sys/atomic.h>
+#include <sys/time.h>
#include <dev/audio_if.h>
#include <dev/audiovar.h>
@@ -316,6 +317,9 @@
if (atomic_swap_uint(&sc->sc_open, 1) != 0) {
return EBUSY;
}
+
+ getmicrotime(&sc->sc_last);
+ sc->sc_bytes_count = 0;
return 0;
}
@@ -335,14 +339,20 @@
return 0;
}
+#define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2)
+#define TIMENEXTREAD (20 * 1000)
+#define BYTESTOSLEEP (PAD_BYTES_PER_SEC / (1000000 / TIMENEXTREAD))
+
int
pad_read(dev_t dev, struct uio *uio, int flags)
{
+ struct timeval now;
+ uint64_t nowusec, lastusec;
pad_softc_t *sc;
pad_block_t pb;
void (*intr)(void *);
void *intrarg;
- int err;
+ int err, wait_ticks;
sc = device_lookup_private(&pad_cd, PADUNIT(dev));
if (sc == NULL)
@@ -354,10 +364,32 @@
intr = sc->sc_intr;
intrarg = sc->sc_intrarg;
- kpreempt_disable();
while (uio->uio_resid > 0 && !err) {
+ getmicrotime(&now);
+ nowusec = (now.tv_sec * 1000000) + now.tv_usec;
+ lastusec = (sc->sc_last.tv_sec * 1000000) +
+ sc->sc_last.tv_usec;
+ if (lastusec + TIMENEXTREAD > nowusec &&
+ sc->sc_bytes_count >= BYTESTOSLEEP) {
+ wait_ticks = (hz * ((lastusec + TIMENEXTREAD) -
+ nowusec)) / 1000000;
+ if (wait_ticks > 0) {
+ kpause("padwait", TRUE, wait_ticks,
+ &sc->sc_lock);
+ }
+
+ sc->sc_bytes_count -= BYTESTOSLEEP;
+ getmicrotime(&sc->sc_last);
+ } else if (sc->sc_bytes_count >= BYTESTOSLEEP) {
+ sc->sc_bytes_count -= BYTESTOSLEEP;
+ getmicrotime(&sc->sc_last);
+ } else if (lastusec + TIMENEXTREAD <= nowusec)
+ getmicrotime(&sc->sc_last);
+
err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE));
if (!err) {
+ sc->sc_bytes_count += pb.pb_len;
+
mutex_exit(&sc->sc_lock);
err = uiomove(pb.pb_ptr, pb.pb_len, uio);
mutex_enter(&sc->sc_lock);
@@ -366,7 +398,9 @@
if (intr) {
mutex_enter(&sc->sc_intr_lock);
+ kpreempt_disable();
(*intr)(intrarg);
+ kpreempt_enable();
mutex_exit(&sc->sc_intr_lock);
intr = sc->sc_intr;
intrarg = sc->sc_intrarg;
@@ -374,22 +408,13 @@
continue;
}
err = cv_wait_sig(&sc->sc_condvar, &sc->sc_lock);
- if (err != 0) {
- mutex_exit(&sc->sc_lock);
- kpreempt_enable();
- return err;
- }
+ if (err != 0)
+ break;
+
intr = sc->sc_intr;
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);
- kpreempt_enable();
return err;
}
diff -r 00e48834a9fa -r 0784ce5bea3d sys/dev/pad/padvar.h
--- a/sys/dev/pad/padvar.h Fri Feb 26 13:08:28 2016 +0000
+++ b/sys/dev/pad/padvar.h Fri Feb 26 13:17:04 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: padvar.h,v 1.5 2014/11/18 01:53:17 jmcneill Exp $ */
+/* $NetBSD: padvar.h,v 1.6 2016/02/26 13:17:04 nat Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -51,6 +51,8 @@
uint32_t sc_rpos, sc_wpos;
uint8_t sc_swvol;
+ struct timeval sc_last;
+ int sc_bytes_count;
} pad_softc_t;
#endif /* !_SYS_DEV_PAD_PADVAR_H */
Home |
Main Index |
Thread Index |
Old Index