Skip to content

Commit

Permalink
ALSA: bcm2835: use a completion instead of a semaphore for sync
Browse files Browse the repository at this point in the history
The kernel completion interface is a simple synchronization
mechanism that is preferable over semaphores to signal the
occurence of an event.

Semaphores are optimized for the non-contention case since
in most situations they will be available. But the wait for
completion is the opposite case since the code calling down
will wait on most cases.

So, is better to use the completion mechanism that has been
developed for this exact use case instead of semaphores.

Signed-off-by: Javier Martinez Canillas <[email protected]>
  • Loading branch information
Javier Martinez Canillas committed Apr 25, 2013
1 parent 31e3bcd commit a9cc473
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions sound/arm/bcm2835-vchiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/module.h>
#include <linux/completion.h>

#include "bcm2835.h"

Expand All @@ -53,7 +54,7 @@
typedef struct opaque_AUDIO_INSTANCE_T {
uint32_t num_connections;
VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
struct semaphore msg_avail_event;
struct completion msg_avail_comp;
struct mutex vchi_mutex;
bcm2835_alsa_stream_t *alsa_stream;
int32_t result;
Expand Down Expand Up @@ -178,7 +179,7 @@ static void audio_vchi_callback(void *param,
(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n",
instance, m.u.result.success);
instance->result = m.u.result.success;
up(&instance->msg_avail_event);
complete(&instance->msg_avail_comp);
} else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
LOG_DBG
Expand Down Expand Up @@ -435,8 +436,8 @@ static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
m.u.control.dest = chip->dest;
m.u.control.volume = chip->volume;

/* Create the message available event */
sema_init(&instance->msg_avail_event, 0);
/* Create the message available completion */
init_completion(&instance->msg_avail_comp);

/* Send the message to the videocore */
success = vchi_msg_queue(instance->vchi_handle[0],
Expand All @@ -452,11 +453,10 @@ static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
}

/* We are expecting a reply from the videocore */
if (down_interruptible(&instance->msg_avail_event)) {
ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
if (ret) {
LOG_ERR("%s: failed on waiting for event (status=%d)\n",
__func__, success);

ret = -1;
goto unlock;
}

Expand Down Expand Up @@ -539,8 +539,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
m.u.config.samplerate = samplerate;
m.u.config.bps = bps;

/* Create the message available event */
sema_init(&instance->msg_avail_event, 0);
/* Create the message available completion */
init_completion(&instance->msg_avail_comp);

/* Send the message to the videocore */
success = vchi_msg_queue(instance->vchi_handle[0],
Expand All @@ -556,11 +556,10 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
}

/* We are expecting a reply from the videocore */
if (down_interruptible(&instance->msg_avail_event)) {
ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
if (ret) {
LOG_ERR("%s: failed on waiting for event (status=%d)\n",
__func__, success);

ret = -1;
goto unlock;
}

Expand Down Expand Up @@ -688,8 +687,8 @@ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)

m.type = VC_AUDIO_MSG_TYPE_CLOSE;

/* Create the message available event */
sema_init(&instance->msg_avail_event, 0);
/* Create the message available completion */
init_completion(&instance->msg_avail_comp);

/* Send the message to the videocore */
success = vchi_msg_queue(instance->vchi_handle[0],
Expand All @@ -702,11 +701,11 @@ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)
ret = -1;
goto unlock;
}
if (down_interruptible(&instance->msg_avail_event)) {

ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
if (ret) {
LOG_ERR("%s: failed on waiting for event (status=%d)",
__func__, success);

ret = -1;
goto unlock;
}
if (instance->result != 0) {
Expand Down

0 comments on commit a9cc473

Please sign in to comment.