diff options
author | Lennart Poettering <lennart@poettering.net> | 2008-04-17 16:28:23 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2008-04-17 16:28:23 +0000 |
commit | 22ceb15bae3251b95fb89c7f2451f3004f62c02f (patch) | |
tree | 6a6769895103c028e9c6c1210d9286731fafc7d2 | |
parent | c9d01592d4aa57f955456a675ebb2281ac5850e1 (diff) |
add new rtstutter tool which can be used generate artifical scheduling latencies in the OS to trigger buffer underrun events in your software. it's an awesome debug tool for glitch-free; also move test programs from automake's check_ back to noinst_ to make sure it is built everytime Lennart presses F9 in his emacs
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2269 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/tests/rtstutter.c | 107 |
2 files changed, 118 insertions, 5 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7139d143..45e3de71 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -226,7 +226,7 @@ pabrowse_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) # Test programs # ################################### -check_PROGRAMS = \ +noinst_PROGRAMS = \ mainloop-test \ mcalign-test \ pacat-simple \ @@ -255,16 +255,17 @@ check_PROGRAMS = \ mix-test \ remix-test \ envelope-test \ - proplist-test + proplist-test \ + rtstutter if HAVE_SIGXCPU -check_PROGRAMS += \ +noinst_PROGRAMS += \ cpulimit-test \ cpulimit-test2 endif if HAVE_GLIB20 -check_PROGRAMS += \ +noinst_PROGRAMS += \ mainloop-test-glib endif @@ -426,10 +427,15 @@ envelope_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) envelope_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) proplist_test_SOURCES = tests/proplist-test.c -proplist_test_LDADD = $(AM_LDADD) libpulse.la +proplist_test_LDADD = $(AM_LDADD) libpulsecore.la proplist_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) proplist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) +rtstutter_SOURCES = tests/rtstutter.c +rtstutter_LDADD = $(AM_LDADD) libpulsecore.la +rtstutter_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) +rtstutter_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) + ################################### # Client library # ################################### diff --git a/src/tests/rtstutter.c b/src/tests/rtstutter.c new file mode 100644 index 00000000..a7d1b042 --- /dev/null +++ b/src/tests/rtstutter.c @@ -0,0 +1,107 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sched.h> +#include <inttypes.h> +#include <string.h> +#include <pthread.h> + +#include <pulse/timeval.h> +#include <pulse/gccmacro.h> + +#include <pulsecore/log.h> +#include <pulsecore/macro.h> + +static int msec; + +static void* work(void *p) PA_GCC_NORETURN; + +static void* work(void *p) { + cpu_set_t mask; + struct sched_param param; + + pa_log_notice("CPU%i: Created thread.", PA_PTR_TO_INT(p)); + + memset(¶m, 0, sizeof(param)); + param.sched_priority = 12; + pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) == 0); + + CPU_ZERO(&mask); + CPU_SET(PA_PTR_TO_INT(p), &mask); + pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0); + + for (;;) { + struct timespec now, end; + uint64_t nsec; + + pa_log_notice("CPU%i: Sleeping for 1s", PA_PTR_TO_INT(p)); + sleep(1); + + pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0); + + nsec = (uint64_t) ((((double) rand())*msec*PA_NSEC_PER_MSEC)/RAND_MAX); + + pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_INT(p), (int) (nsec/PA_NSEC_PER_MSEC)); + + end.tv_sec += nsec / PA_NSEC_PER_SEC; + end.tv_nsec += nsec % PA_NSEC_PER_SEC; + + while (end.tv_nsec > PA_NSEC_PER_SEC) { + end.tv_sec++; + end.tv_nsec -= PA_NSEC_PER_SEC; + } + + do { + pa_assert_se(clock_gettime(CLOCK_REALTIME, &now) == 0); + } while (now.tv_sec < end.tv_sec || + (now.tv_sec == end.tv_sec && now.tv_nsec < end.tv_nsec)); + } +} + +int main(int argc, char*argv[]) { + int n; + + srand(time(NULL)); + + msec = argc > 1 ? atoi(argv[1]) : 1000; + + pa_assert(msec > 0); + + pa_log_notice("Creating random latencies of up to %ims.", msec); + + for (n = 1; n < sysconf(_SC_NPROCESSORS_CONF); n++) { + pthread_t t; + pa_assert_se(pthread_create(&t, NULL, work, PA_INT_TO_PTR(n)) == 0); + } + + work(PA_INT_TO_PTR(0)); + + return 0; +} |