[alsa-devel] [PATCH 1/2] ALSA: pcm - Ensure wakeup at each periodic interrupt
jassi brar
jassisinghbrar at gmail.com
Tue Dec 22 08:34:32 CET 2009
On Mon, Dec 21, 2009 at 8:28 PM, Takashi Iwai <tiwai at suse.de> wrote:
> At Thu, 17 Dec 2009 17:21:28 +0900,
> jassi brar wrote:
>>
>> On Thu, Dec 17, 2009 at 4:43 PM, Takashi Iwai <tiwai at suse.de> wrote:
>> > At Thu, 17 Dec 2009 16:31:08 +0900,
>> > jassi brar wrote:
>> >>
>> >> On Thu, Dec 17, 2009 at 4:02 PM, Takashi Iwai <tiwai at suse.de> wrote:
>> >> > At Thu, 17 Dec 2009 15:00:02 +0900,
>> >> > jassisinghbrar at gmail.com wrote:
>> >> >>
>> >> >> From: Jassi Brar <jassi.brar at samsung.com>
>> >> >>
>> >> >> The check for at least 'avail_min' available data before calling wake_up
>> >> >> doesn't always hold good as it does not guarantee callbacks at each periodic
>> >> >> interrupt.
>> >> >
>> >> > Well, avail_min can be greater than period_size. And, avail_min won't be
>> >> > less than period size.
>> >> >
>> >> > For example, when avail_min = 2.5 x period_size, the driver wakes up
>> >> > in periods like 3, 2, 3, 2, ...
>> >> correct, but if we ensure wake_up's after each period and let the 'sleepers'
>> >> track if the data available is enough or not, we will have more fine grained
>> >> control.
>> >> The point is:- Waking up _after_ avail_min is working, but does waking up before
>> >> avail_min(but at period boundary) break the system?
>> >
>> > PulseAudio may complain :)
>> I meant effects on ALSA state-machine within the kernel.
>> >From what i have seen, every use of sleep is just to kill some time,
>> i.e, wake_up
>> is not taken as indication of completion of the purpose.
>
> It's used also for poll.
>
> Meanwhile, we may change snd_pcm_*_poll() function itself, too...
How about employing a new snd_pcm_runtime member (say, need_min) which
denote the _exact_ minimum amount of data needed to serve purpose
of last sleep ?
Quick idea of what i mean, follows. If you like it, i will resend the
patches again
Thanks.
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index de6d981..b5a9e81 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -267,6 +267,7 @@ struct snd_pcm_runtime {
struct snd_pcm_substream *trigger_master;
struct timespec trigger_tstamp; /* trigger timestamp */
int overrange;
+ snd_pcm_uframes_t need_min; /* exact minimum needed before wakeup */
snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 30f4108..a689add 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -208,7 +208,7 @@ static int snd_pcm_update_hw_ptr_post(struct
snd_pcm_substream *substream,
return -EPIPE;
}
}
- if (avail >= runtime->control->avail_min)
+ if (avail >= runtime->need_min)
wake_up(&runtime->sleep);
return 0;
}
@@ -1681,6 +1681,7 @@ static int wait_for_avail_min(struct
snd_pcm_substream *substream,
break;
}
set_current_state(TASK_INTERRUPTIBLE);
+ runtime->need_min = *availp;
snd_pcm_stream_unlock_irq(substream);
tout = schedule_timeout(msecs_to_jiffies(10000));
snd_pcm_stream_lock_irq(substream);
@@ -1788,6 +1789,7 @@ static snd_pcm_sframes_t
snd_pcm_lib_write1(struct snd_pcm_substream *substream,
err = -EAGAIN;
goto _end_unlock;
}
+ avail = size;
err = wait_for_avail_min(substream, &avail);
if (err < 0)
goto _end_unlock;
@@ -2010,6 +2012,7 @@ static snd_pcm_sframes_t
snd_pcm_lib_read1(struct snd_pcm_substream *substream,
err = -EAGAIN;
goto _end_unlock;
}
+ avail = size;
err = wait_for_avail_min(substream, &avail);
if (err < 0)
goto _end_unlock;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ab73edf..6e5dfa2 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2892,6 +2892,10 @@ static unsigned int
snd_pcm_playback_poll(struct file *file, poll_table * wait)
return -ENXIO;
runtime = substream->runtime;
+ snd_pcm_stream_lock_irq(substream);
+ runtime->need_min = runtime->control->avail_min;
+ snd_pcm_stream_unlock_irq(substream);
+
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(substream);
@@ -2931,6 +2935,10 @@ static unsigned int snd_pcm_capture_poll(struct
file *file, poll_table * wait)
return -ENXIO;
runtime = substream->runtime;
+ snd_pcm_stream_lock_irq(substream);
+ runtime->need_min = runtime->control->avail_min;
+ snd_pcm_stream_unlock_irq(substream);
+
poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(substream);
More information about the Alsa-devel
mailing list