Skip to content

Commit

Permalink
ALSA: rawmidi - Use workq for event handling
Browse files Browse the repository at this point in the history
Kill tasklet usage in rawmidi core code.  Use workq for the event callback
instead of tasklet (which is used only in core/seq/seq_midi.c).

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Jun 14, 2011
1 parent 30bdee0 commit b3c705a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 27 deletions.
4 changes: 3 additions & 1 deletion include/sound/rawmidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>

#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
#include "seq_device.h"
Expand Down Expand Up @@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops {
};

struct snd_rawmidi_runtime {
struct snd_rawmidi_substream *substream;
unsigned int drain: 1, /* drain stage */
oss: 1; /* OSS compatible mode */
/* midi stream buffer */
Expand All @@ -79,7 +81,7 @@ struct snd_rawmidi_runtime {
/* event handler (new bytes, input only) */
void (*event)(struct snd_rawmidi_substream *substream);
/* defers calls to event [input] or ops->trigger [output] */
struct tasklet_struct tasklet;
struct work_struct event_work;
/* private data */
void *private_data;
void (*private_free)(struct snd_rawmidi_substream *substream);
Expand Down
37 changes: 11 additions & 26 deletions sound/core/rawmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
(!substream->append || runtime->avail >= count);
}

static void snd_rawmidi_input_event_tasklet(unsigned long data)
static void snd_rawmidi_input_event_work(struct work_struct *work)
{
struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
substream->runtime->event(substream);
}

static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
{
struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
substream->ops->trigger(substream, 1);
struct snd_rawmidi_runtime *runtime =
container_of(work, struct snd_rawmidi_runtime, event_work);
if (runtime->event)
runtime->event(runtime->substream);
}

static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
Expand All @@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)

if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
return -ENOMEM;
runtime->substream = substream;
spin_lock_init(&runtime->lock);
init_waitqueue_head(&runtime->sleep);
if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
tasklet_init(&runtime->tasklet,
snd_rawmidi_input_event_tasklet,
(unsigned long)substream);
else
tasklet_init(&runtime->tasklet,
snd_rawmidi_output_trigger_tasklet,
(unsigned long)substream);
INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
runtime->event = NULL;
runtime->buffer_size = PAGE_SIZE;
runtime->avail_min = 1;
Expand Down Expand Up @@ -150,21 +140,16 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
{
if (!substream->opened)
return;
if (up) {
tasklet_schedule(&substream->runtime->tasklet);
} else {
tasklet_kill(&substream->runtime->tasklet);
substream->ops->trigger(substream, 0);
}
substream->ops->trigger(substream, up);
}

static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
if (!substream->opened)
return;
substream->ops->trigger(substream, up);
if (!up && substream->runtime->event)
tasklet_kill(&substream->runtime->tasklet);
if (!up)
cancel_work_sync(&substream->runtime->event_work);
}

int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
Expand Down Expand Up @@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
}
if (result > 0) {
if (runtime->event)
tasklet_schedule(&runtime->tasklet);
schedule_work(&runtime->event_work);
else if (snd_rawmidi_ready(substream))
wake_up(&runtime->sleep);
}
Expand Down

0 comments on commit b3c705a

Please sign in to comment.