summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-04-17 16:28:23 +0000
committerLennart Poettering <lennart@poettering.net>2008-04-17 16:28:23 +0000
commit22ceb15bae3251b95fb89c7f2451f3004f62c02f (patch)
tree6a6769895103c028e9c6c1210d9286731fafc7d2
parentc9d01592d4aa57f955456a675ebb2281ac5850e1 (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.am16
-rw-r--r--src/tests/rtstutter.c107
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(&param, 0, sizeof(param));
+ param.sched_priority = 12;
+ pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) == 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;
+}