From 2741685d3ad4e78c1c155f77cea34c46c259584e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 00:32:51 +0000 Subject: [PATCH] use priority inheritance on mutexes where applicable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1837 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 16 ++++++++++++++++ src/daemon/main.c | 2 +- src/modules/module-combine.c | 2 +- src/pulse/thread-mainloop.c | 2 +- src/pulsecore/asyncmsgq.c | 2 +- src/pulsecore/memblock.c | 16 ++++++++++------ src/pulsecore/mutex-posix.c | 9 +++++++-- src/pulsecore/mutex.h | 10 +++++++++- src/pulsecore/once-posix.c | 2 +- src/tests/thread-test.c | 2 +- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index f179827..c12cfc0 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,22 @@ AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll]) ACX_PTHREAD +AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT]) +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ +#include +int main() { int i = PTHREAD_PRIO_INHERIT; }]])]) +$PTHREAD_CC conftest.c $PTHREAD_CFLAGS $CFLAGS $PTHREAD_LIBS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest + +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + + #### Large File-Support (LFS) #### AC_SYS_LARGEFILE diff --git a/src/daemon/main.c b/src/daemon/main.c index e01bb23..f34e59e 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -330,7 +330,7 @@ static const char *libtool_get_error(void) { } static void libtool_init(void) { - pa_assert_se(libtool_mutex = pa_mutex_new(1)); + pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); pa_assert_se(lt_dlinit() == 0); } diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 235e04e..7ac7b9a 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -947,7 +947,7 @@ int pa__init(pa_module*m) { u->thread_info.master = u->master = NULL; u->time_event = NULL; u->adjust_time = DEFAULT_ADJUST_TIME; - u->mutex = pa_mutex_new(0); + u->mutex = pa_mutex_new(FALSE, TRUE); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = NULL; u->thread = NULL; diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 29769e2..3068570 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -103,7 +103,7 @@ pa_threaded_mainloop *pa_threaded_mainloop_new(void) { return NULL; } - m->mutex = pa_mutex_new(1); + m->mutex = pa_mutex_new(TRUE, FALSE); m->cond = pa_cond_new(); m->accept_cond = pa_cond_new(); m->thread = NULL; diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index b365446..c0917ca 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -67,7 +67,7 @@ pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { PA_REFCNT_INIT(a); pa_assert_se(a->asyncq = pa_asyncq_new(size)); - pa_assert_se(a->mutex = pa_mutex_new(0)); + pa_assert_se(a->mutex = pa_mutex_new(FALSE, TRUE)); a->current = NULL; return a; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 05fc34d..3827dc0 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -660,7 +660,7 @@ pa_mempool* pa_mempool_new(int shared) { p = pa_xnew(pa_mempool, 1); - p->mutex = pa_mutex_new(1); + p->mutex = pa_mutex_new(TRUE, TRUE); p->semaphore = pa_semaphore_new(0); p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE); @@ -781,7 +781,7 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void pa_assert(cb); i = pa_xnew(pa_memimport, 1); - i->mutex = pa_mutex_new(1); + i->mutex = pa_mutex_new(TRUE, TRUE); i->pool = p; i->segments = pa_hashmap_new(NULL, NULL); i->blocks = pa_hashmap_new(NULL, NULL); @@ -909,18 +909,22 @@ finish: int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memblock *b; + int ret = 0; pa_assert(i); pa_mutex_lock(i->mutex); - if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) - return -1; + if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) { + ret = -1; + goto finish; + } memblock_replace_import(b); +finish: pa_mutex_unlock(i->mutex); - return 0; + return ret; } /* For sending blocks to other nodes */ @@ -934,7 +938,7 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void return NULL; e = pa_xnew(pa_memexport, 1); - e->mutex = pa_mutex_new(1); + e->mutex = pa_mutex_new(TRUE, TRUE); e->pool = p; PA_LLIST_HEAD_INIT(struct memexport_slot, e->free_slots); PA_LLIST_HEAD_INIT(struct memexport_slot, e->used_slots); diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c index 64f466d..19e095b 100644 --- a/src/pulsecore/mutex-posix.c +++ b/src/pulsecore/mutex-posix.c @@ -40,15 +40,20 @@ struct pa_cond { pthread_cond_t cond; }; -pa_mutex* pa_mutex_new(int recursive) { +pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) { pa_mutex *m; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); - + if (recursive) pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0); +#ifdef HAVE_PTHREAD_PRIO_INHERIT + if (inherit_priority) + pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); +#endif + m = pa_xnew(pa_mutex, 1); pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); return m; diff --git a/src/pulsecore/mutex.h b/src/pulsecore/mutex.h index b2e34c0..72e8878 100644 --- a/src/pulsecore/mutex.h +++ b/src/pulsecore/mutex.h @@ -24,9 +24,17 @@ USA. ***/ +#include + typedef struct pa_mutex pa_mutex; -pa_mutex* pa_mutex_new(int recursive); +/* Please think twice before enabling priority inheritance. This is no + * magic wand! Use it only when the potentially priorized threads are + * good candidates for it. Don't use this blindly! Also, note that + * only very few operating systems actually implement this, hence this + * is merely a hint. */ +pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority); + void pa_mutex_free(pa_mutex *m); void pa_mutex_lock(pa_mutex *m); void pa_mutex_unlock(pa_mutex *m); diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index fba0ddf..4f6e5b6 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -58,7 +58,7 @@ int pa_once_begin(pa_once *control) { return 0; } - pa_assert_se(m = pa_mutex_new(0)); + pa_assert_se(m = pa_mutex_new(FALSE, FALSE)); pa_mutex_lock(m); if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) diff --git a/src/tests/thread-test.c b/src/tests/thread-test.c index 0077cde..72dde6c 100644 --- a/src/tests/thread-test.c +++ b/src/tests/thread-test.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) { assert(pa_thread_is_running(pa_thread_self())); - mutex = pa_mutex_new(0); + mutex = pa_mutex_new(FALSE, FALSE); cond1 = pa_cond_new(); cond2 = pa_cond_new(); tls = pa_tls_new(pa_xfree); -- 2.7.4