[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/6] audio: Use QEMU threads & synchronization
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 5/6] audio: Use QEMU threads & synchronization |
Date: |
Tue, 20 Sep 2011 18:53:12 +0200 |
This both simplifies error handling and enables central management of
threads and locks.
CC: malc <address@hidden>
Signed-off-by: Jan Kiszka <address@hidden>
---
audio/audio_pt_int.c | 167 ++-----------------------------------------------
audio/audio_pt_int.h | 45 ++++++++++----
audio/esdaudio.c | 92 ++++++++--------------------
audio/paaudio.c | 84 ++++++++-----------------
4 files changed, 91 insertions(+), 297 deletions(-)
diff --git a/audio/audio_pt_int.c b/audio/audio_pt_int.c
index 9a9c306..d47bd63 100644
--- a/audio/audio_pt_int.c
+++ b/audio/audio_pt_int.c
@@ -6,168 +6,15 @@
#include "audio_int.h"
#include "audio_pt_int.h"
-static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
- const char *fmt, ...)
+void audio_pt_init (struct audio_pt *p, void *(*func) (void *), void *opaque)
{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (pt->drv, fmt, ap);
- va_end (ap);
-
- AUD_log (NULL, "\n");
- AUD_log (pt->drv, "Reason: %s\n", strerror (err));
-}
-
-int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
- void *opaque, const char *drv, const char *cap)
-{
- int err, err2;
- const char *efunc;
- sigset_t set, old_set;
-
- p->drv = drv;
-
- err = sigfillset (&set);
- if (err) {
- logerr (p, errno, "%s(%s): sigfillset failed", cap, AUDIO_FUNC);
- return -1;
- }
-
- err = pthread_mutex_init (&p->mutex, NULL);
- if (err) {
- efunc = "pthread_mutex_init";
- goto err0;
- }
-
- err = pthread_cond_init (&p->cond, NULL);
- if (err) {
- efunc = "pthread_cond_init";
- goto err1;
- }
-
- err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
- if (err) {
- efunc = "pthread_sigmask";
- goto err2;
- }
-
- err = pthread_create (&p->thread, NULL, func, opaque);
-
- err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_sigmask (restore) failed",
- cap, AUDIO_FUNC);
- /* We have failed to restore original signal mask, all bets are off,
- so terminate the process */
- exit (EXIT_FAILURE);
- }
-
- if (err) {
- efunc = "pthread_create";
- goto err2;
- }
-
- return 0;
-
- err2:
- err2 = pthread_cond_destroy (&p->cond);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap,
AUDIO_FUNC);
- }
-
- err1:
- err2 = pthread_mutex_destroy (&p->mutex);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap,
AUDIO_FUNC);
- }
-
- err0:
- logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
- return -1;
+ qemu_mutex_init(&p->mutex);
+ qemu_cond_init(&p->cond);
+ qemu_thread_create(&p->thread, func, opaque, QEMU_THREAD_JOINABLE);
}
-int audio_pt_fini (struct audio_pt *p, const char *cap)
+void audio_pt_fini (struct audio_pt *p)
{
- int err, ret = 0;
-
- err = pthread_cond_destroy (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap,
AUDIO_FUNC);
- ret = -1;
- }
-
- err = pthread_mutex_destroy (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap,
AUDIO_FUNC);
- ret = -1;
- }
- return ret;
-}
-
-int audio_pt_lock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_lock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap,
AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_wait (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_cond_wait (&p->cond, &p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap,
AUDIO_FUNC);
- return -1;
- }
- err = pthread_cond_signal (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
-{
- int err;
- void *ret;
-
- err = pthread_join (p->thread, &ret);
- if (err) {
- logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
- return -1;
- }
- *arg = ret;
- return 0;
+ qemu_cond_destroy(&p->cond);
+ qemu_mutex_destroy(&p->mutex);
}
diff --git a/audio/audio_pt_int.h b/audio/audio_pt_int.h
index 0dfff76..e395f7d 100644
--- a/audio/audio_pt_int.h
+++ b/audio/audio_pt_int.h
@@ -1,22 +1,41 @@
#ifndef QEMU_AUDIO_PT_INT_H
#define QEMU_AUDIO_PT_INT_H
-#include <pthread.h>
+#include "qemu-thread.h"
struct audio_pt {
- const char *drv;
- pthread_t thread;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
+ QemuThread thread;
+ QemuCond cond;
+ QemuMutex mutex;
};
-int audio_pt_init (struct audio_pt *, void *(*) (void *), void *,
- const char *, const char *);
-int audio_pt_fini (struct audio_pt *, const char *);
-int audio_pt_lock (struct audio_pt *, const char *);
-int audio_pt_unlock (struct audio_pt *, const char *);
-int audio_pt_wait (struct audio_pt *, const char *);
-int audio_pt_unlock_and_signal (struct audio_pt *, const char *);
-int audio_pt_join (struct audio_pt *, void **, const char *);
+void audio_pt_init (struct audio_pt *, void *(*) (void *), void *);
+void audio_pt_fini (struct audio_pt *);
+
+static inline void audio_pt_lock (struct audio_pt *p)
+{
+ qemu_mutex_lock(&p->mutex);
+}
+
+static inline void audio_pt_unlock (struct audio_pt *p)
+{
+ qemu_mutex_unlock(&p->mutex);
+}
+
+static inline void audio_pt_wait (struct audio_pt *p)
+{
+ qemu_cond_wait(&p->cond, &p->mutex);
+}
+
+static inline void audio_pt_unlock_and_signal (struct audio_pt *p)
+{
+ qemu_mutex_unlock(&p->mutex);
+ qemu_cond_signal(&p->cond);
+}
+
+static inline void audio_pt_join (struct audio_pt *p)
+{
+ qemu_thread_join(&p->thread);
+}
#endif /* audio_pt_int.h */
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
index bd6e1cc..fd1b25d 100644
--- a/audio/esdaudio.c
+++ b/audio/esdaudio.c
@@ -81,9 +81,7 @@ static void *qesd_thread_out (void *arg)
threshold = conf.divisor ? hw->samples / conf.divisor : 0;
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&esd->pt);
for (;;) {
int decr, to_mix, rpos;
@@ -97,17 +95,13 @@ static void *qesd_thread_out (void *arg)
break;
}
- if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
- goto exit;
- }
+ audio_pt_wait (&esd->pt);
}
decr = to_mix = esd->live;
rpos = hw->rpos;
- if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_unlock (&esd->pt);
while (to_mix) {
ssize_t written;
@@ -143,9 +137,7 @@ static void *qesd_thread_out (void *arg)
to_mix -= chunk;
}
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&esd->pt);
esd->rpos = rpos;
esd->live -= decr;
@@ -153,7 +145,7 @@ static void *qesd_thread_out (void *arg)
}
exit:
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock (&esd->pt);
return NULL;
}
@@ -162,19 +154,17 @@ static int qesd_run_out (HWVoiceOut *hw, int live)
int decr;
ESDVoiceOut *esd = (ESDVoiceOut *) hw;
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return 0;
- }
+ audio_pt_lock (&esd->pt);
decr = audio_MIN (live, esd->decr);
esd->decr -= decr;
esd->live = live - decr;
hw->rpos = esd->rpos;
if (esd->live > 0) {
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&esd->pt);
}
else {
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock (&esd->pt);
}
return decr;
}
@@ -232,19 +222,10 @@ static int qesd_init_out (HWVoiceOut *hw, struct
audsettings *as)
goto fail1;
}
- if (audio_pt_init (&esd->pt, qesd_thread_out, esd, AUDIO_CAP, AUDIO_FUNC))
{
- goto fail2;
- }
+ audio_pt_init (&esd->pt, qesd_thread_out, esd);
return 0;
- fail2:
- if (close (esd->fd)) {
- qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
- AUDIO_FUNC, esd->fd);
- }
- esd->fd = -1;
-
fail1:
g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
@@ -253,13 +234,12 @@ static int qesd_init_out (HWVoiceOut *hw, struct
audsettings *as)
static void qesd_fini_out (HWVoiceOut *hw)
{
- void *ret;
ESDVoiceOut *esd = (ESDVoiceOut *) hw;
- audio_pt_lock (&esd->pt, AUDIO_FUNC);
+ audio_pt_lock (&esd->pt);
esd->done = 1;
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&esd->pt);
+ audio_pt_join (&esd->pt);
if (esd->fd >= 0) {
if (close (esd->fd)) {
@@ -268,7 +248,7 @@ static void qesd_fini_out (HWVoiceOut *hw)
esd->fd = -1;
}
- audio_pt_fini (&esd->pt, AUDIO_FUNC);
+ audio_pt_fini (&esd->pt);
g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
@@ -290,9 +270,7 @@ static void *qesd_thread_in (void *arg)
threshold = conf.divisor ? hw->samples / conf.divisor : 0;
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&esd->pt);
for (;;) {
int incr, to_grab, wpos;
@@ -306,17 +284,13 @@ static void *qesd_thread_in (void *arg)
break;
}
- if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
- goto exit;
- }
+ audio_pt_wait (&esd->pt);
}
incr = to_grab = esd->dead;
wpos = hw->wpos;
- if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_unlock (&esd->pt);
while (to_grab) {
ssize_t nread;
@@ -351,9 +325,7 @@ static void *qesd_thread_in (void *arg)
to_grab -= chunk;
}
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&esd->pt);
esd->wpos = wpos;
esd->dead -= incr;
@@ -361,7 +333,7 @@ static void *qesd_thread_in (void *arg)
}
exit:
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock (&esd->pt);
return NULL;
}
@@ -370,9 +342,7 @@ static int qesd_run_in (HWVoiceIn *hw)
int live, incr, dead;
ESDVoiceIn *esd = (ESDVoiceIn *) hw;
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return 0;
- }
+ audio_pt_lock (&esd->pt);
live = audio_pcm_hw_get_live_in (hw);
dead = hw->samples - live;
@@ -381,10 +351,10 @@ static int qesd_run_in (HWVoiceIn *hw)
esd->dead = dead - incr;
hw->wpos = esd->wpos;
if (esd->dead > 0) {
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&esd->pt);
}
else {
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
+ audio_pt_unlock (&esd->pt);
}
return incr;
}
@@ -439,19 +409,10 @@ static int qesd_init_in (HWVoiceIn *hw, struct
audsettings *as)
goto fail1;
}
- if (audio_pt_init (&esd->pt, qesd_thread_in, esd, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail2;
- }
+ audio_pt_init (&esd->pt, qesd_thread_in, esd);
return 0;
- fail2:
- if (close (esd->fd)) {
- qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
- AUDIO_FUNC, esd->fd);
- }
- esd->fd = -1;
-
fail1:
g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
@@ -460,13 +421,12 @@ static int qesd_init_in (HWVoiceIn *hw, struct
audsettings *as)
static void qesd_fini_in (HWVoiceIn *hw)
{
- void *ret;
ESDVoiceIn *esd = (ESDVoiceIn *) hw;
- audio_pt_lock (&esd->pt, AUDIO_FUNC);
+ audio_pt_lock (&esd->pt);
esd->done = 1;
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&esd->pt);
+ audio_pt_join (&esd->pt);
if (esd->fd >= 0) {
if (close (esd->fd)) {
@@ -475,7 +435,7 @@ static void qesd_fini_in (HWVoiceIn *hw)
esd->fd = -1;
}
- audio_pt_fini (&esd->pt, AUDIO_FUNC);
+ audio_pt_fini (&esd->pt);
g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
diff --git a/audio/paaudio.c b/audio/paaudio.c
index d1f3912..b539a72 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -56,9 +56,7 @@ static void *qpa_thread_out (void *arg)
PAVoiceOut *pa = arg;
HWVoiceOut *hw = &pa->hw;
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&pa->pt);
for (;;) {
int decr, to_mix, rpos;
@@ -72,17 +70,13 @@ static void *qpa_thread_out (void *arg)
break;
}
- if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
- goto exit;
- }
+ audio_pt_wait (&pa->pt);
}
decr = to_mix = audio_MIN (pa->live, conf.samples >> 2);
rpos = pa->rpos;
- if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_unlock (&pa->pt);
while (to_mix) {
int error;
@@ -101,9 +95,7 @@ static void *qpa_thread_out (void *arg)
to_mix -= chunk;
}
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&pa->pt);
pa->rpos = rpos;
pa->live -= decr;
@@ -111,7 +103,7 @@ static void *qpa_thread_out (void *arg)
}
exit:
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock (&pa->pt);
return NULL;
}
@@ -120,19 +112,17 @@ static int qpa_run_out (HWVoiceOut *hw, int live)
int decr;
PAVoiceOut *pa = (PAVoiceOut *) hw;
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return 0;
- }
+ audio_pt_lock (&pa->pt);
decr = audio_MIN (live, pa->decr);
pa->decr -= decr;
pa->live = live - decr;
hw->rpos = pa->rpos;
if (pa->live > 0) {
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&pa->pt);
}
else {
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock (&pa->pt);
}
return decr;
}
@@ -148,9 +138,7 @@ static void *qpa_thread_in (void *arg)
PAVoiceIn *pa = arg;
HWVoiceIn *hw = &pa->hw;
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&pa->pt);
for (;;) {
int incr, to_grab, wpos;
@@ -164,17 +152,13 @@ static void *qpa_thread_in (void *arg)
break;
}
- if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
- goto exit;
- }
+ audio_pt_wait (&pa->pt);
}
incr = to_grab = audio_MIN (pa->dead, conf.samples >> 2);
wpos = pa->wpos;
- if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_unlock (&pa->pt);
while (to_grab) {
int error;
@@ -192,9 +176,7 @@ static void *qpa_thread_in (void *arg)
to_grab -= chunk;
}
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return NULL;
- }
+ audio_pt_lock (&pa->pt);
pa->wpos = wpos;
pa->dead -= incr;
@@ -202,7 +184,7 @@ static void *qpa_thread_in (void *arg)
}
exit:
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock (&pa->pt);
return NULL;
}
@@ -211,9 +193,7 @@ static int qpa_run_in (HWVoiceIn *hw)
int live, incr, dead;
PAVoiceIn *pa = (PAVoiceIn *) hw;
- if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
- return 0;
- }
+ audio_pt_lock (&pa->pt);
live = audio_pcm_hw_get_live_in (hw);
dead = hw->samples - live;
@@ -222,10 +202,10 @@ static int qpa_run_in (HWVoiceIn *hw)
pa->dead = dead - incr;
hw->wpos = pa->wpos;
if (pa->dead > 0) {
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&pa->pt);
}
else {
- audio_pt_unlock (&pa->pt, AUDIO_FUNC);
+ audio_pt_unlock (&pa->pt);
}
return incr;
}
@@ -332,15 +312,10 @@ static int qpa_init_out (HWVoiceOut *hw, struct
audsettings *as)
goto fail2;
}
- if (audio_pt_init (&pa->pt, qpa_thread_out, hw, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
+ audio_pt_init (&pa->pt, qpa_thread_out, hw);
return 0;
- fail3:
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
fail2:
pa_simple_free (pa->s);
pa->s = NULL;
@@ -387,15 +362,10 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings
*as)
goto fail2;
}
- if (audio_pt_init (&pa->pt, qpa_thread_in, hw, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
+ audio_pt_init (&pa->pt, qpa_thread_in, hw);
return 0;
- fail3:
- g_free (pa->pcm_buf);
- pa->pcm_buf = NULL;
fail2:
pa_simple_free (pa->s);
pa->s = NULL;
@@ -405,40 +375,38 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings
*as)
static void qpa_fini_out (HWVoiceOut *hw)
{
- void *ret;
PAVoiceOut *pa = (PAVoiceOut *) hw;
- audio_pt_lock (&pa->pt, AUDIO_FUNC);
+ audio_pt_lock (&pa->pt);
pa->done = 1;
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&pa->pt);
+ audio_pt_join (&pa->pt);
if (pa->s) {
pa_simple_free (pa->s);
pa->s = NULL;
}
- audio_pt_fini (&pa->pt, AUDIO_FUNC);
+ audio_pt_fini (&pa->pt);
g_free (pa->pcm_buf);
pa->pcm_buf = NULL;
}
static void qpa_fini_in (HWVoiceIn *hw)
{
- void *ret;
PAVoiceIn *pa = (PAVoiceIn *) hw;
- audio_pt_lock (&pa->pt, AUDIO_FUNC);
+ audio_pt_lock (&pa->pt);
pa->done = 1;
- audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
- audio_pt_join (&pa->pt, &ret, AUDIO_FUNC);
+ audio_pt_unlock_and_signal (&pa->pt);
+ audio_pt_join (&pa->pt);
if (pa->s) {
pa_simple_free (pa->s);
pa->s = NULL;
}
- audio_pt_fini (&pa->pt, AUDIO_FUNC);
+ audio_pt_fini (&pa->pt);
g_free (pa->pcm_buf);
pa->pcm_buf = NULL;
}
--
1.7.3.4