pcm: dmix: Fix semaphore usage with lockless operation

As Maarten Baert recently reported, the current dmix code applies the
semaphore unnecessarily around mixing streams even when the lockless
mix operation is used on x86.  This was rather introduced mistakenly
at the commit 267d7c7281 ("Add support of little-endian on
i386/x86_64 dmix") where the generic dmix code was included on x86,
too.

For achieving the original performance back, this patch changes the
semaphore handling to be checked at run time instead of statically at
compile time.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2020-06-19 18:40:46 +02:00
parent 4759865c86
commit d824b461ae
5 changed files with 15 additions and 8 deletions

View file

@ -186,6 +186,7 @@ struct snd_pcm_direct {
mix_areas_32_t *remix_areas_32; mix_areas_32_t *remix_areas_32;
mix_areas_24_t *remix_areas_24; mix_areas_24_t *remix_areas_24;
mix_areas_u8_t *remix_areas_u8; mix_areas_u8_t *remix_areas_u8;
unsigned int use_sem;
} dmix; } dmix;
struct { struct {
unsigned long long chn_mask; unsigned long long chn_mask;

View file

@ -292,13 +292,17 @@ static void remix_areas(snd_pcm_direct_t *dmix,
* the area via semaphore * the area via semaphore
*/ */
#ifndef DOC_HIDDEN #ifndef DOC_HIDDEN
#ifdef NO_CONCURRENT_ACCESS static void dmix_down_sem(snd_pcm_direct_t *dmix)
#define dmix_down_sem(dmix) snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT) {
#define dmix_up_sem(dmix) snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT) if (dmix->u.dmix.use_sem)
#else snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
#define dmix_down_sem(dmix) }
#define dmix_up_sem(dmix)
#endif static void dmix_up_sem(snd_pcm_direct_t *dmix)
{
if (dmix->u.dmix.use_sem)
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
}
#endif #endif
/* /*

View file

@ -43,7 +43,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
#ifndef ARCH_ADD #ifndef ARCH_ADD
#define ARCH_ADD(p,a) (*(p) += (a)) #define ARCH_ADD(p,a) (*(p) += (a))
#define ARCH_CMPXCHG(p,a,b) (*(p)) /* fake */ #define ARCH_CMPXCHG(p,a,b) (*(p)) /* fake */
#define NO_CONCURRENT_ACCESS /* use semaphore to avoid race */
#define IS_CONCURRENT 0 /* no race check */ #define IS_CONCURRENT 0 /* no race check */
#endif #endif
@ -530,6 +529,7 @@ static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8; dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
dmix->u.dmix.remix_areas_24 = generic_remix_areas_24; dmix->u.dmix.remix_areas_24 = generic_remix_areas_24;
dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8; dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8;
dmix->u.dmix.use_sem = 1;
} }
#endif #endif

View file

@ -135,4 +135,5 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24; dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24; dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
} }
dmix->u.dmix.use_sem = 0;
} }

View file

@ -102,4 +102,5 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32; dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp : mix_areas_24; dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp : mix_areas_24;
dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp : remix_areas_24; dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp : remix_areas_24;
dmix->u.dmix.use_sem = 0;
} }