[alsa-devel] [PATCH 2/2] ASoC: dapm: Add cache to speed up adding of routes

Mark Brown broonie at kernel.org
Thu May 7 14:48:11 CEST 2015


On Thu, May 07, 2015 at 11:33:59AM +0100, Charles Keepax wrote:
> Some CODECs have a significant number of DAPM routes and for each route,
> when it is added to the card, the entire card widget list must be

The idea here is good but I'm having a hard time loving the
implementation.  It feels like it's hacking this specific implementation
in many different places without really abstracting things - having a
neat trick hidden in one place would be one thinng but it's spread
through several different places.

> +static struct snd_soc_dapm_widget *
> +dapm_check_path_cache(const char *name, struct snd_soc_dapm_widget *w, int n)
> +{
> +	int i;
> +
> +	if (w) {
> +		for (i = 0; i < n; i++) {
> +			if (!strcmp(name, w->name))
> +				return w;
> +
> +			w = list_next_entry(w, list);
> +		}

This will not be happy if there are fewer than n entries to look at.

>  static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
> -				  const struct snd_soc_dapm_route *route)
> +				  const struct snd_soc_dapm_route *route,
> +				  struct snd_soc_dapm_path *cache)

The fact that we're directly using the path structure as the type for
the cache here is a warning flag, it means that everywhere that knows
there is a cache at all needs to know about the specific type of the
cache.  If we were to improve the cache in the future, for example doing
something like building a hash that maps names to widgets for the
duration of probe, then everywhere would need to change.

> +	if (cache) {
> +		wsink = dapm_check_path_cache(sink, cache->sink, 2);
> +		wsource = dapm_check_path_cache(source, cache->source, 2);
> +
> +		if (wsink && wsource)
> +			goto skip_search;
> +	}
> +

This is the only place where we have _check_path_cache() calls so n is
always 2 here and it is unclear where that number comes from or what it
means without going and peering at the implementation and the commit
log.  It seems it would be better to hide that number inside the
function.

> +skip_search:
> +	if (cache) {
> +		cache->sink = wsink;
> +		cache->source = wsource;
> +	}
> +

Putting this into a store hit function would be good.

>  	mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
>  	for (i = 0; i < num; i++) {
> -		r = snd_soc_dapm_add_route(dapm, route);
> +		r = snd_soc_dapm_add_route(dapm, route, &cache);

Should we just have the cache in the dapm context or the card instead of
locally?  It's only two pointers at the minute so there doesn't seem to
be much cost from keeping it around and it might generate somme more
hits for some use cases.  Or to put it another way why is the cache
optional and created and re-created here like this?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20150507/9b003655/attachment.sig>


More information about the Alsa-devel mailing list