use priority inheritance on mutexes where applicable
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Sep 2007 00:32:51 +0000 (00:32 +0000)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Sep 2007 00:32:51 +0000 (00:32 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1837 fefdeb5f-60dc-0310-8127-8f9354f1896f

configure.ac
src/daemon/main.c
src/modules/module-combine.c
src/pulse/thread-mainloop.c
src/pulsecore/asyncmsgq.c
src/pulsecore/memblock.c
src/pulsecore/mutex-posix.c
src/pulsecore/mutex.h
src/pulsecore/once-posix.c
src/tests/thread-test.c

index f179827..c12cfc0 100644 (file)
@@ -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 <pthread.h> 
+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
index e01bb23..f34e59e 100644 (file)
@@ -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);
 }
index 235e04e..7ac7b9a 100644 (file)
@@ -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;
index 29769e2..3068570 100644 (file)
@@ -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;
index b365446..c0917ca 100644 (file)
@@ -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;
index 05fc34d..3827dc0 100644 (file)
@@ -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);
index 64f466d..19e095b 100644 (file)
@@ -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;
index b2e34c0..72e8878 100644 (file)
   USA.
 ***/
 
+#include <pulsecore/macro.h>
+
 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);
index fba0ddf..4f6e5b6 100644 (file)
@@ -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))
index 0077cde..72dde6c 100644 (file)
@@ -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);