Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31e8960b authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela
Browse files

[ALSA] Remove PCM sleep_min and tick



The 'tick' in PCM is set (again) via sw_params.  And, nobody uses
this feature at all except for a command line option of aplay.
(This is literally 'nobody', as I checked alsa-lib API calls in all
 programs in major distros.)
Above all, if we need finer wake-ups for the position update, it's
basically an issue that the driver should solve, not tuned by each
application.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 13075510
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -274,7 +274,6 @@ struct snd_pcm_runtime {
	snd_pcm_uframes_t period_size;	/* period size */
	unsigned int periods;		/* periods */
	snd_pcm_uframes_t buffer_size;	/* buffer size */
	unsigned int tick_time;		/* tick time */
	snd_pcm_uframes_t min_align;	/* Min alignment for the format */
	size_t byte_align;
	unsigned int frame_bits;
@@ -286,7 +285,6 @@ struct snd_pcm_runtime {
	/* -- SW params -- */
	int tstamp_mode;		/* mmap timestamp is updated */
  	unsigned int period_step;
	unsigned int sleep_min;		/* min ticks to sleep */
	snd_pcm_uframes_t start_threshold;
	snd_pcm_uframes_t stop_threshold;
	snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
@@ -305,7 +303,6 @@ struct snd_pcm_runtime {

	/* -- locking / scheduling -- */
	wait_queue_head_t sleep;
	struct timer_list tick_timer;
	struct fasync_struct *fasync;

	/* -- private section -- */
@@ -810,7 +807,6 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc
#define params_periods(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_PERIODS)->min
#define params_buffer_size(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min
#define params_buffer_bytes(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min
#define params_tick_time(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_TICK_TIME)->min


int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v);
@@ -908,9 +904,6 @@ int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream);
int snd_pcm_playback_xrun_asap(struct snd_pcm_substream *substream);
int snd_pcm_capture_xrun_asap(struct snd_pcm_substream *substream);
void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr);
void snd_pcm_tick_prepare(struct snd_pcm_substream *substream);
void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks);
void snd_pcm_tick_elapsed(struct snd_pcm_substream *substream);
void snd_pcm_period_elapsed(struct snd_pcm_substream *substream);
snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream,
				    const void __user *buf,
+0 −1
Original line number Diff line number Diff line
@@ -985,7 +985,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
		sw_params->stop_threshold = runtime->buffer_size;
	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
	sw_params->period_step = 1;
	sw_params->sleep_min = 0;
	sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
		1 : runtime->period_size;
	if (atomic_read(&substream->mmap_count) ||
+0 −11
Original line number Diff line number Diff line
@@ -359,7 +359,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
	snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);	
	snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);	
	snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);	
	snd_iprintf(buffer, "tick_time: %u\n", runtime->tick_time);
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
	if (substream->oss.oss) {
		snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
@@ -387,7 +386,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
	}
	snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
	snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
	snd_iprintf(buffer, "sleep_min: %u\n", runtime->sleep_min);
	snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);
	snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);
	snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);
@@ -764,12 +762,6 @@ static int snd_pcm_dev_free(struct snd_device *device)
	return snd_pcm_free(pcm);
}

static void snd_pcm_tick_timer_func(unsigned long data)
{
	struct snd_pcm_substream *substream = (struct snd_pcm_substream *) data;
	snd_pcm_tick_elapsed(substream);
}

int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
			     struct file *file,
			     struct snd_pcm_substream **rsubstream)
@@ -876,9 +868,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
	memset((void*)runtime->control, 0, size);

	init_waitqueue_head(&runtime->sleep);
	init_timer(&runtime->tick_timer);
	runtime->tick_timer.function = snd_pcm_tick_timer_func;
	runtime->tick_timer.data = (unsigned long) substream;

	runtime->status->state = SNDRV_PCM_STATE_OPEN;

+3 −110
Original line number Diff line number Diff line
@@ -1451,112 +1451,13 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,

EXPORT_SYMBOL(snd_pcm_lib_ioctl);

/*
 *  Conditions
 */

static void snd_pcm_system_tick_set(struct snd_pcm_substream *substream, 
				    unsigned long ticks)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	if (ticks == 0)
		del_timer(&runtime->tick_timer);
	else {
		ticks += (1000000 / HZ) - 1;
		ticks /= (1000000 / HZ);
		mod_timer(&runtime->tick_timer, jiffies + ticks);
	}
}

/* Temporary alias */
void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks)
{
	snd_pcm_system_tick_set(substream, ticks);
}

void snd_pcm_tick_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_pcm_uframes_t frames = ULONG_MAX;
	snd_pcm_uframes_t avail, dist;
	unsigned int ticks;
	u_int64_t n;
	u_int32_t r;
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		if (runtime->silence_size >= runtime->boundary) {
			frames = 1;
		} else if (runtime->silence_size > 0 &&
			   runtime->silence_filled < runtime->buffer_size) {
			snd_pcm_sframes_t noise_dist;
			noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
			if (noise_dist > (snd_pcm_sframes_t)runtime->silence_threshold)
				frames = noise_dist - runtime->silence_threshold;
		}
		avail = snd_pcm_playback_avail(runtime);
	} else {
		avail = snd_pcm_capture_avail(runtime);
	}
	if (avail < runtime->control->avail_min) {
		snd_pcm_sframes_t to_avail_min =
			runtime->control->avail_min - avail;
		if (to_avail_min > 0 &&
		    frames > (snd_pcm_uframes_t)to_avail_min)
			frames = to_avail_min;
	}
	if (avail < runtime->buffer_size) {
		snd_pcm_sframes_t to_buffer_size =
			runtime->buffer_size - avail;
		if (to_buffer_size > 0 &&
		    frames > (snd_pcm_uframes_t)to_buffer_size)
			frames = to_buffer_size;
	}
	if (frames == ULONG_MAX) {
		snd_pcm_tick_set(substream, 0);
		return;
	}
	dist = runtime->status->hw_ptr - runtime->hw_ptr_base;
	/* Distance to next interrupt */
	dist = runtime->period_size - dist % runtime->period_size;
	if (dist <= frames) {
		snd_pcm_tick_set(substream, 0);
		return;
	}
	/* the base time is us */
	n = frames;
	n *= 1000000;
	div64_32(&n, runtime->tick_time * runtime->rate, &r);
	ticks = n + (r > 0 ? 1 : 0);
	if (ticks < runtime->sleep_min)
		ticks = runtime->sleep_min;
	snd_pcm_tick_set(substream, (unsigned long) ticks);
}

void snd_pcm_tick_elapsed(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime;
	unsigned long flags;
	
	snd_assert(substream != NULL, return);
	runtime = substream->runtime;
	snd_assert(runtime != NULL, return);

	snd_pcm_stream_lock_irqsave(substream, flags);
	if (!snd_pcm_running(substream) ||
	    snd_pcm_update_hw_ptr(substream) < 0)
		goto _end;
	if (runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
 _end:
	snd_pcm_stream_unlock_irqrestore(substream, flags);
}

/**
 * snd_pcm_period_elapsed - update the pcm status for the next period
 * @substream: the pcm substream instance
 *
 * This function is called from the interrupt handler when the
 * PCM has processed the period size.  It will update the current
 * pointer, set up the tick, wake up sleepers, etc.
 * pointer, wake up sleepers, etc.
 *
 * Even if more than one periods have elapsed since the last call, you
 * have to call this only once.
@@ -1580,8 +1481,6 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)

	if (substream->timer_running)
		snd_timer_interrupt(substream->timer, 1);
	if (runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
 _end:
	snd_pcm_stream_unlock_irqrestore(substream, flags);
	if (runtime->transfer_ack_end)
@@ -1715,7 +1614,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
		snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
		snd_pcm_uframes_t avail;
		snd_pcm_uframes_t cont;
		if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
			snd_pcm_update_hw_ptr(substream);
		avail = snd_pcm_playback_avail(runtime);
		if (!avail) {
@@ -1764,9 +1663,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
			if (err < 0)
				goto _end_unlock;
		}
		if (runtime->sleep_min &&
		    runtime->status->state == SNDRV_PCM_STATE_RUNNING)
			snd_pcm_tick_prepare(substream);
	}
 _end_unlock:
	snd_pcm_stream_unlock_irq(substream);
@@ -1923,7 +1819,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
		snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
		snd_pcm_uframes_t avail;
		snd_pcm_uframes_t cont;
		if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
			snd_pcm_update_hw_ptr(substream);
		avail = snd_pcm_capture_avail(runtime);
		if (!avail) {
@@ -1973,9 +1869,6 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
		offset += frames;
		size -= frames;
		xfer += frames;
		if (runtime->sleep_min &&
		    runtime->status->state == SNDRV_PCM_STATE_RUNNING)
			snd_pcm_tick_prepare(substream);
	}
 _end_unlock:
	snd_pcm_stream_unlock_irq(substream);
+0 −30
Original line number Diff line number Diff line
@@ -413,7 +413,6 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
	runtime->period_size = params_period_size(params);
	runtime->periods = params_periods(params);
	runtime->buffer_size = params_buffer_size(params);
	runtime->tick_time = params_tick_time(params);
	runtime->info = params->info;
	runtime->rate_num = params->rate_num;
	runtime->rate_den = params->rate_den;
@@ -433,7 +432,6 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
	/* Default sw params */
	runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
	runtime->period_step = 1;
	runtime->sleep_min = 0;
	runtime->control->avail_min = runtime->period_size;
	runtime->start_threshold = 1;
	runtime->stop_threshold = runtime->buffer_size;
@@ -542,7 +540,6 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
	}
	snd_pcm_stream_lock_irq(substream);
	runtime->tstamp_mode = params->tstamp_mode;
	runtime->sleep_min = params->sleep_min;
	runtime->period_step = params->period_step;
	runtime->control->avail_min = params->avail_min;
	runtime->start_threshold = params->start_threshold;
@@ -551,10 +548,6 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
	runtime->silence_size = params->silence_size;
        params->boundary = runtime->boundary;
	if (snd_pcm_running(substream)) {
		if (runtime->sleep_min)
			snd_pcm_tick_prepare(substream);
		else
			snd_pcm_tick_set(substream, 0);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
		    runtime->silence_size > 0)
			snd_pcm_playback_silence(substream, ULONG_MAX);
@@ -865,8 +858,6 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
	    runtime->silence_size > 0)
		snd_pcm_playback_silence(substream, ULONG_MAX);
	if (runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
	if (substream->timer)
		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
				 &runtime->trigger_tstamp);
@@ -920,7 +911,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
					 &runtime->trigger_tstamp);
		runtime->status->state = state;
		snd_pcm_tick_set(substream, 0);
	}
	wake_up(&runtime->sleep);
}
@@ -1004,12 +994,9 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
			snd_timer_notify(substream->timer,
					 SNDRV_TIMER_EVENT_MPAUSE,
					 &runtime->trigger_tstamp);
		snd_pcm_tick_set(substream, 0);
		wake_up(&runtime->sleep);
	} else {
		runtime->status->state = SNDRV_PCM_STATE_RUNNING;
		if (runtime->sleep_min)
			snd_pcm_tick_prepare(substream);
		if (substream->timer)
			snd_timer_notify(substream->timer,
					 SNDRV_TIMER_EVENT_MCONTINUE,
@@ -1064,7 +1051,6 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
				 &runtime->trigger_tstamp);
	runtime->status->suspended_state = runtime->status->state;
	runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
	snd_pcm_tick_set(substream, 0);
	wake_up(&runtime->sleep);
}

@@ -1167,8 +1153,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
				 &runtime->trigger_tstamp);
	runtime->status->state = runtime->status->suspended_state;
	if (runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
}

static struct action_ops snd_pcm_action_resume = {
@@ -1997,8 +1981,6 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
	}

	/* FIXME: this belong to lowlevel */
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_TICK_TIME,
				     1000000 / HZ, 1000000 / HZ);
	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);

	return 0;
@@ -2238,9 +2220,6 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
	if (appl_ptr < 0)
		appl_ptr += runtime->boundary;
	runtime->control->appl_ptr = appl_ptr;
	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
	    runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
	ret = frames;
 __end:
	snd_pcm_stream_unlock_irq(substream);
@@ -2286,9 +2265,6 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
	if (appl_ptr < 0)
		appl_ptr += runtime->boundary;
	runtime->control->appl_ptr = appl_ptr;
	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
	    runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
	ret = frames;
 __end:
	snd_pcm_stream_unlock_irq(substream);
@@ -2335,9 +2311,6 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
	if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
		appl_ptr -= runtime->boundary;
	runtime->control->appl_ptr = appl_ptr;
	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
	    runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
	ret = frames;
 __end:
	snd_pcm_stream_unlock_irq(substream);
@@ -2384,9 +2357,6 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
	if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
		appl_ptr -= runtime->boundary;
	runtime->control->appl_ptr = appl_ptr;
	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
	    runtime->sleep_min)
		snd_pcm_tick_prepare(substream);
	ret = frames;
 __end:
	snd_pcm_stream_unlock_irq(substream);