Sat Jun 10 06:05:48 2017 UTC ()
Pull up following revision(s) (requested by nat in ticket #20):
	sys/dev/pad/pad.c: revisions 1.33-1.35
	sys/dev/pad/padvar.h: revision 1.9
Express BYTESTOSLEEP as an 64 bit integer.
Use BYTESTOSLEEP in expresson of BYTES_PER_SEC.
--
sc_bytes_count needs to be set in pad_audio_open not pad_open.
--
Simplification of rate limiter.  It now works uni/multiprocessor.
--
pad blocksize 1024 -> 8192.  Helps when sleeping in rate limiter.


(snj)
diff -r1.32 -r1.32.2.1 src/sys/dev/pad/pad.c
diff -r1.8 -r1.8.2.1 src/sys/dev/pad/padvar.h

cvs diff -r1.32 -r1.32.2.1 src/sys/dev/pad/pad.c (expand / switch to unified diff)

--- src/sys/dev/pad/pad.c 2017/06/01 09:44:30 1.32
+++ src/sys/dev/pad/pad.c 2017/06/10 06:05:47 1.32.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pad.c,v 1.32 2017/06/01 09:44:30 pgoyette Exp $ */ 1/* $NetBSD: pad.c,v 1.32.2.1 2017/06/10 06:05:47 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.32 2017/06/01 09:44:30 pgoyette Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.32.2.1 2017/06/10 06:05:47 snj Exp $");
31 31
32#include <sys/types.h> 32#include <sys/types.h>
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/conf.h> 34#include <sys/conf.h>
35#include <sys/buf.h> 35#include <sys/buf.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/proc.h> 39#include <sys/proc.h>
40#include <sys/condvar.h> 40#include <sys/condvar.h>
41#include <sys/select.h> 41#include <sys/select.h>
42#include <sys/audioio.h> 42#include <sys/audioio.h>
43#include <sys/vnode.h> 43#include <sys/vnode.h>
@@ -312,51 +312,47 @@ pad_detach(device_t self, int flags) @@ -312,51 +312,47 @@ pad_detach(device_t self, int flags)
312int 312int
313pad_open(dev_t dev, int flags, int fmt, struct lwp *l) 313pad_open(dev_t dev, int flags, int fmt, struct lwp *l)
314{ 314{
315 pad_softc_t *sc; 315 pad_softc_t *sc;
316 316
317 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 317 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
318 if (sc == NULL) 318 if (sc == NULL)
319 return ENXIO; 319 return ENXIO;
320 320
321 if (atomic_swap_uint(&sc->sc_open, 1) != 0) { 321 if (atomic_swap_uint(&sc->sc_open, 1) != 0) {
322 return EBUSY; 322 return EBUSY;
323 } 323 }
324  324
325 getmicrotime(&sc->sc_last); 
326 sc->sc_bytes_count = 0; 
327 sc->sc_remainder = 0; 
328 
329 return 0; 325 return 0;
330} 326}
331 327
332int 328int
333pad_close(dev_t dev, int flags, int fmt, struct lwp *l) 329pad_close(dev_t dev, int flags, int fmt, struct lwp *l)
334{ 330{
335 pad_softc_t *sc; 331 pad_softc_t *sc;
336 332
337 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 333 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
338 if (sc == NULL) 334 if (sc == NULL)
339 return ENXIO; 335 return ENXIO;
340 336
341 KASSERT(sc->sc_open > 0); 337 KASSERT(sc->sc_open > 0);
342 sc->sc_open = 0; 338 sc->sc_open = 0;
343 339
344 return 0; 340 return 0;
345} 341}
346 342
347#define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2) 343#define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2)
348#define TIMENEXTREAD (PAD_BLKSIZE * 1000000 / PAD_BYTES_PER_SEC) 344#define BYTESTOSLEEP (int64_t)(PAD_BLKSIZE)
349#define BYTESTOSLEEP (PAD_BLKSIZE) 345#define TIMENEXTREAD (int64_t)(BYTESTOSLEEP * 1000000 / PAD_BYTES_PER_SEC)
350 346
351int 347int
352pad_read(dev_t dev, struct uio *uio, int flags) 348pad_read(dev_t dev, struct uio *uio, int flags)
353{ 349{
354 struct timeval now; 350 struct timeval now;
355 uint64_t nowusec, lastusec; 351 uint64_t nowusec, lastusec;
356 pad_softc_t *sc; 352 pad_softc_t *sc;
357 pad_block_t pb; 353 pad_block_t pb;
358 void (*intr)(void *); 354 void (*intr)(void *);
359 void *intrarg; 355 void *intrarg;
360 int err, wait_ticks; 356 int err, wait_ticks;
361 357
362 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 358 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
@@ -364,50 +360,46 @@ pad_read(dev_t dev, struct uio *uio, int @@ -364,50 +360,46 @@ pad_read(dev_t dev, struct uio *uio, int
364 return ENXIO; 360 return ENXIO;
365 361
366 err = 0; 362 err = 0;
367 363
368 while (uio->uio_resid > 0 && !err) { 364 while (uio->uio_resid > 0 && !err) {
369 mutex_enter(&sc->sc_lock); 365 mutex_enter(&sc->sc_lock);
370 intr = sc->sc_intr; 366 intr = sc->sc_intr;
371 intrarg = sc->sc_intrarg; 367 intrarg = sc->sc_intrarg;
372 368
373 getmicrotime(&now); 369 getmicrotime(&now);
374 nowusec = (now.tv_sec * 1000000) + now.tv_usec; 370 nowusec = (now.tv_sec * 1000000) + now.tv_usec;
375 lastusec = (sc->sc_last.tv_sec * 1000000) + 371 lastusec = (sc->sc_last.tv_sec * 1000000) +
376 sc->sc_last.tv_usec; 372 sc->sc_last.tv_usec;
377 if (lastusec + TIMENEXTREAD > nowusec && 373 if (lastusec + TIMENEXTREAD > nowusec) {
378 sc->sc_bytes_count >= BYTESTOSLEEP) { 374 if (sc->sc_bytes_count >= BYTESTOSLEEP) {
379 sc->sc_remainder += 375 sc->sc_remainder +=
380 ((lastusec + TIMENEXTREAD) - nowusec); 376 ((lastusec + TIMENEXTREAD) - nowusec);
 377 }
381  378
382 wait_ticks = (hz * sc->sc_remainder) / 1000000; 379 wait_ticks = (hz * sc->sc_remainder) / 1000000;
383 if (wait_ticks > 0) { 380 if (wait_ticks > 0) {
384 sc->sc_remainder -= wait_ticks * 1000000 / hz; 381 sc->sc_remainder -= wait_ticks * 1000000 / hz;
385 kpause("padwait", TRUE, wait_ticks, 382 kpause("padwait", TRUE, wait_ticks,
386 &sc->sc_lock); 383 &sc->sc_lock);
387 } 384 }
 385 }
388 386
 387 if (sc->sc_bytes_count >= BYTESTOSLEEP)
389 sc->sc_bytes_count -= BYTESTOSLEEP; 388 sc->sc_bytes_count -= BYTESTOSLEEP;
390 getmicrotime(&sc->sc_last); 
391 } else if (sc->sc_bytes_count >= BYTESTOSLEEP) { 
392 sc->sc_bytes_count -= BYTESTOSLEEP; 
393 getmicrotime(&sc->sc_last); 
394 } else if (lastusec + TIMENEXTREAD <= nowusec) { 
395 getmicrotime(&sc->sc_last); 
396 sc->sc_remainder = 0; 
397 } 
398 389
399 err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE)); 390 err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE));
400 if (!err) { 391 if (!err) {
 392 getmicrotime(&sc->sc_last);
401 sc->sc_bytes_count += pb.pb_len; 393 sc->sc_bytes_count += pb.pb_len;
402 mutex_exit(&sc->sc_lock); 394 mutex_exit(&sc->sc_lock);
403 err = uiomove(pb.pb_ptr, pb.pb_len, uio); 395 err = uiomove(pb.pb_ptr, pb.pb_len, uio);
404 continue; 396 continue;
405 } 397 }
406 398
407 if (intr) { 399 if (intr) {
408 mutex_enter(&sc->sc_intr_lock); 400 mutex_enter(&sc->sc_intr_lock);
409 kpreempt_disable(); 401 kpreempt_disable();
410 (*intr)(intrarg); 402 (*intr)(intrarg);
411 kpreempt_enable(); 403 kpreempt_enable();
412 mutex_exit(&sc->sc_intr_lock); 404 mutex_exit(&sc->sc_intr_lock);
413 intr = sc->sc_intr; 405 intr = sc->sc_intr;
@@ -428,26 +420,27 @@ pad_read(dev_t dev, struct uio *uio, int @@ -428,26 +420,27 @@ pad_read(dev_t dev, struct uio *uio, int
428 return err; 420 return err;
429} 421}
430 422
431static int 423static int
432pad_audio_open(void *opaque, int flags) 424pad_audio_open(void *opaque, int flags)
433{ 425{
434 pad_softc_t *sc; 426 pad_softc_t *sc;
435 sc = opaque; 427 sc = opaque;
436 428
437 if (sc->sc_open == 0) 429 if (sc->sc_open == 0)
438 return EIO; 430 return EIO;
439 431
440 getmicrotime(&sc->sc_last); 432 getmicrotime(&sc->sc_last);
 433 sc->sc_bytes_count = 0;
441 sc->sc_remainder = 0; 434 sc->sc_remainder = 0;
442 435
443 return 0; 436 return 0;
444} 437}
445 438
446static int 439static int
447pad_query_encoding(void *opaque, struct audio_encoding *ae) 440pad_query_encoding(void *opaque, struct audio_encoding *ae)
448{ 441{
449 pad_softc_t *sc; 442 pad_softc_t *sc;
450 443
451 sc = (pad_softc_t *)opaque; 444 sc = (pad_softc_t *)opaque;
452 445
453 KASSERT(mutex_owned(&sc->sc_lock)); 446 KASSERT(mutex_owned(&sc->sc_lock));

cvs diff -r1.8 -r1.8.2.1 src/sys/dev/pad/padvar.h (expand / switch to unified diff)

--- src/sys/dev/pad/padvar.h 2017/05/27 10:02:26 1.8
+++ src/sys/dev/pad/padvar.h 2017/06/10 06:05:47 1.8.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: padvar.h,v 1.8 2017/05/27 10:02:26 nat Exp $ */ 1/* $NetBSD: padvar.h,v 1.8.2.1 2017/06/10 06:05:47 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -34,26 +34,26 @@ typedef struct pad_softc { @@ -34,26 +34,26 @@ typedef struct pad_softc {
34 34
35 u_int sc_open; 35 u_int sc_open;
36 struct audio_encoding_set *sc_encodings; 36 struct audio_encoding_set *sc_encodings;
37 void (*sc_intr)(void *); 37 void (*sc_intr)(void *);
38 void *sc_intrarg; 38 void *sc_intrarg;
39 39
40 kcondvar_t sc_condvar; 40 kcondvar_t sc_condvar;
41 kmutex_t sc_lock; 41 kmutex_t sc_lock;
42 kmutex_t sc_intr_lock; 42 kmutex_t sc_intr_lock;
43 43
44 struct audio_softc *sc_audiodev; 44 struct audio_softc *sc_audiodev;
45 int sc_blksize; 45 int sc_blksize;
46 46
47#define PAD_BLKSIZE 1024 47#define PAD_BLKSIZE 8192
48#define PAD_BUFSIZE 65536 48#define PAD_BUFSIZE 65536
49 uint8_t sc_audiobuf[PAD_BUFSIZE]; 49 uint8_t sc_audiobuf[PAD_BUFSIZE];
50 uint32_t sc_buflen; 50 uint32_t sc_buflen;
51 uint32_t sc_rpos, sc_wpos; 51 uint32_t sc_rpos, sc_wpos;
52 52
53 uint8_t sc_swvol; 53 uint8_t sc_swvol;
54 struct timeval sc_last; 54 struct timeval sc_last;
55 int sc_bytes_count; 55 int sc_bytes_count;
56 uint32_t sc_remainder; 56 uint32_t sc_remainder;
57} pad_softc_t; 57} pad_softc_t;
58 58
59#endif /* !_SYS_DEV_PAD_PADVAR_H */ 59#endif /* !_SYS_DEV_PAD_PADVAR_H */