mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-23 08:56:45 -05:00
Generic architecture support
Support dmix on generic architectures without atomic operations but using a semaphore to avoid concurrent accesses. This is less effective than atomic operations but should work on every system.
This commit is contained in:
parent
6a6a70ffe7
commit
9207804912
2 changed files with 15 additions and 5 deletions
|
|
@ -228,8 +228,15 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm, snd_pcm_uframes_t size)
|
||||||
transfer = appl_ptr + size > pcm->buffer_size ? pcm->buffer_size - appl_ptr : size;
|
transfer = appl_ptr + size > pcm->buffer_size ? pcm->buffer_size - appl_ptr : size;
|
||||||
if (slave_appl_ptr + transfer > dmix->shmptr->s.buffer_size)
|
if (slave_appl_ptr + transfer > dmix->shmptr->s.buffer_size)
|
||||||
transfer = dmix->shmptr->s.buffer_size - slave_appl_ptr;
|
transfer = dmix->shmptr->s.buffer_size - slave_appl_ptr;
|
||||||
if (transfer)
|
if (transfer) {
|
||||||
|
#ifdef NO_CONCURRENT_ACCESS
|
||||||
|
snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
#endif
|
||||||
mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
|
mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
|
||||||
|
#ifdef NO_CONCURRENT_ACCESS
|
||||||
|
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (transfer >= size)
|
if (transfer >= size)
|
||||||
return;
|
return;
|
||||||
size -= transfer;
|
size -= transfer;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if 0
|
||||||
|
//#if defined(__i386__) || defined(__x86_64__)
|
||||||
#define LOCK_PREFIX "lock ; "
|
#define LOCK_PREFIX "lock ; "
|
||||||
#define ARCH_ADD(p,a) \
|
#define ARCH_ADD(p,a) \
|
||||||
__asm__ __volatile__(LOCK_PREFIX "addl %1,%0" \
|
__asm__ __volatile__(LOCK_PREFIX "addl %1,%0" \
|
||||||
|
|
@ -36,12 +37,14 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||||
#define ARCH_CMPXCHG(ptr,o,n)\
|
#define ARCH_CMPXCHG(ptr,o,n)\
|
||||||
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
|
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
|
||||||
(unsigned long)(n),sizeof(*(ptr))))
|
(unsigned long)(n),sizeof(*(ptr))))
|
||||||
|
#define IS_CONCURRENT 1 /* check race */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARCH_ADD
|
#ifndef ARCH_ADD
|
||||||
#warning Please, define atomic ADD and CMPXCHG for your architecture...
|
|
||||||
#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 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void mix_areas1(unsigned int size,
|
static void mix_areas1(unsigned int size,
|
||||||
|
|
@ -69,7 +72,7 @@ static void mix_areas1(unsigned int size,
|
||||||
else
|
else
|
||||||
sample = old_sample;
|
sample = old_sample;
|
||||||
*dst = sample;
|
*dst = sample;
|
||||||
} while (*sum != old_sample);
|
} while (IS_CONCURRENT && *sum != old_sample);
|
||||||
if (!--size)
|
if (!--size)
|
||||||
return;
|
return;
|
||||||
src += src_step;
|
src += src_step;
|
||||||
|
|
@ -103,7 +106,7 @@ static void mix_areas2(unsigned int size,
|
||||||
else
|
else
|
||||||
sample = old_sample * 256;
|
sample = old_sample * 256;
|
||||||
*dst = sample;
|
*dst = sample;
|
||||||
} while (*sum != old_sample);
|
} while (IS_CONCURRENT && *sum != old_sample);
|
||||||
if (!--size)
|
if (!--size)
|
||||||
return;
|
return;
|
||||||
src += src_step;
|
src += src_step;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue