daemon: add nice value in service file to improve performance
[platform/upstream/pulseaudio.git] / src / pulsecore / mutex-posix.c
index b3e5256..865df53 100644 (file)
@@ -14,9 +14,7 @@
   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.
+  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 ***/
 
 #ifdef HAVE_CONFIG_H
 
 #include <pthread.h>
 #include <errno.h>
+#ifdef __TIZEN__
+#include <sys/time.h>
+#endif
 
 #include <pulse/xmalloc.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/log.h>
+
 #include <pulsecore/core-error.h>
+#include <pulsecore/macro.h>
 
 #include "mutex.h"
 
+#ifdef __TIZEN__
 struct pa_mutex {
+    unsigned int lock;
     pthread_mutex_t mutex;
+    unsigned int unlock;
 };
+#else
+struct pa_mutex {
+    pthread_mutex_t mutex;
+};
+#endif
 
 struct pa_cond {
     pthread_cond_t cond;
 };
 
-pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {
+pa_mutex* pa_mutex_new(bool recursive, bool inherit_priority) {
     pa_mutex *m;
     pthread_mutexattr_t attr;
+#ifdef HAVE_PTHREAD_PRIO_INHERIT
     int r;
+#endif
 
     pa_assert_se(pthread_mutexattr_init(&attr) == 0);
 
@@ -52,8 +63,10 @@ pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {
         pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0);
 
 #ifdef HAVE_PTHREAD_PRIO_INHERIT
-    if (inherit_priority)
-        pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) == 0);
+    if (inherit_priority) {
+        r = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+        pa_assert(r == 0 || r == ENOTSUP);
+    }
 #endif
 
     m = pa_xnew(pa_mutex, 1);
@@ -74,38 +87,76 @@ pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {
     }
 #endif
 
+#ifdef __TIZEN__
+    m->lock = 0;
+    m->unlock = 0;
+#endif
+
     return m;
 }
 
 void pa_mutex_free(pa_mutex *m) {
+#ifdef __TIZEN__
+    int ret;
+#endif
     pa_assert(m);
 
+#ifdef __TIZEN__
+    ret = pthread_mutex_destroy(&m->mutex);
+    if (ret != 0)
+        pa_log_error("pthread_mutex_destroy [%p] error [%d], (%d/%d)", &m->mutex, ret, m->lock, m->unlock);
+    pa_assert_se(ret == 0);
+#else
     pa_assert_se(pthread_mutex_destroy(&m->mutex) == 0);
+#endif
     pa_xfree(m);
 }
 
 void pa_mutex_lock(pa_mutex *m) {
+#ifdef __TIZEN__
+    int ret;
+#endif
     pa_assert(m);
 
+#ifdef __TIZEN__
+    ret = pthread_mutex_lock(&m->mutex);
+    if (ret != 0)
+        pa_log_error("pthread_mutex_lock [%p] error [%d], (%d/%d)", &m->mutex, ret, m->lock, m->unlock);
+    pa_assert_se(ret == 0);
+    m->lock++;
+#else
     pa_assert_se(pthread_mutex_lock(&m->mutex) == 0);
+#endif
 }
 
-pa_bool_t pa_mutex_try_lock(pa_mutex *m) {
+bool pa_mutex_try_lock(pa_mutex *m) {
     int r;
     pa_assert(m);
 
     if ((r = pthread_mutex_trylock(&m->mutex)) != 0) {
         pa_assert(r == EBUSY);
-        return FALSE;
+        return false;
     }
 
-    return TRUE;
+    return true;
 }
 
 void pa_mutex_unlock(pa_mutex *m) {
+    int err;
+
     pa_assert(m);
 
-    pa_assert_se(pthread_mutex_unlock(&m->mutex) == 0);
+    if ((err = pthread_mutex_unlock(&m->mutex)) != 0) {
+#ifdef __TIZEN__
+        pa_log_error("pthread_mutex_unlock [%p] error [%d], (%d/%d)", &m->mutex, err, m->lock, m->unlock);
+#else
+        pa_log("pthread_mutex_unlock() failed: %s", pa_cstrerror(err));
+#endif
+        pa_assert_not_reached();
+    }
+#ifdef __TIZEN__
+    m->unlock++;
+#endif
 }
 
 pa_cond *pa_cond_new(void) {
@@ -139,7 +190,30 @@ int pa_cond_wait(pa_cond *c, pa_mutex *m) {
     return pthread_cond_wait(&c->cond, &m->mutex);
 }
 
-pa_mutex* pa_static_mutex_get(pa_static_mutex *s, pa_bool_t recursive, pa_bool_t inherit_priority) {
+#ifdef __TIZEN__
+int pa_cond_timedwait(pa_cond *c, pa_mutex *m, int ms_to_wait) {
+    struct timeval now;
+    struct timeval wait;
+    struct timeval wait_until;
+    struct timespec wait_until_ts;
+
+    pa_assert(c);
+    pa_assert(m);
+
+    gettimeofday(&now, NULL);
+
+    wait.tv_sec = ms_to_wait / 1000L;
+    wait.tv_usec = (ms_to_wait % 1000L) * 1000L;
+
+    timeradd(&now, &wait, &wait_until);
+
+    wait_until_ts.tv_sec = wait_until.tv_sec;
+    wait_until_ts.tv_nsec = wait_until.tv_usec * 1000L;
+
+    return pthread_cond_timedwait(&c->cond, &m->mutex, &wait_until_ts);
+}
+#endif
+pa_mutex* pa_static_mutex_get(pa_static_mutex *s, bool recursive, bool inherit_priority) {
     pa_mutex *m;
 
     pa_assert(s);
@@ -153,6 +227,8 @@ pa_mutex* pa_static_mutex_get(pa_static_mutex *s, pa_bool_t recursive, pa_bool_t
     if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
         return m;
 
+    pa_mutex_free(m);
+
     /* Him, filling in failed, so someone else must have filled in
      * already */
     pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));