]> git.alsa-project.org Git - alsa-lib.git/commitdiff
<atlka@pg.gda.pl>
authorJaroslav Kysela <perex@perex.cz>
Sat, 24 Jan 2004 16:34:35 +0000 (16:34 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 24 Jan 2004 16:34:35 +0000 (16:34 +0000)
- shm memory patch
- optimized a bit sample mixing routines in c and x_86 asm

src/pcm/pcm_direct.c
src/pcm/pcm_dmix.c
src/pcm/pcm_dmix_i386.h
src/pcm/pcm_mmap.c
src/shmarea.c

index 44fada7fcb9d50c2ae7f5da134398f5991be265b..12a8f0db80d4ce35f0f4104fabbadca8bf2c6cdd 100644 (file)
@@ -101,11 +101,21 @@ int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix)
 {
        static int snd_pcm_direct_shm_discard(snd_pcm_direct_t *dmix);
        struct shmid_ds buf;
-       int ret = 0;
+       int tmpid, err;
        
+retryget:
        dmix->shmid = shmget(dmix->ipc_key, sizeof(snd_pcm_direct_share_t), IPC_CREAT | 0666);
-       if (dmix->shmid < 0)
-               return -errno;
+       err = -errno;
+       if (dmix->shmid < 0){
+               if (errno == EINVAL)
+               if ((tmpid = shmget(dmix->ipc_key, 0, 0666)) != -1)
+               if (!shmctl(tmpid, IPC_STAT, &buf))
+               if (!buf.shm_nattch)
+               /* no users so destroy the segment */
+               if (!shmctl(tmpid, IPC_RMID, NULL))
+                   goto retryget;
+               return err;
+       }
        dmix->shmptr = shmat(dmix->shmid, 0, 0);
        if (dmix->shmptr == (void *) -1) {
                snd_pcm_direct_shm_discard(dmix);
@@ -118,9 +128,9 @@ int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix)
        }
        if (buf.shm_nattch == 1) {      /* we're the first user, clear the segment */
                memset(dmix->shmptr, 0, sizeof(snd_pcm_direct_share_t));
-               ret = 1;
+               return 1;
        }
-       return ret;
+       return 0;
 }
 
 int snd_pcm_direct_shm_discard(snd_pcm_direct_t *dmix)
index 7865cbe493ed61cfc3f184846af8beecb211b8fa..8473d9c01356e9618033c6c2825cfa3de670cae1 100644 (file)
@@ -59,14 +59,26 @@ const char *_snd_module_pcm_dmix = "";
 static int shm_sum_create_or_connect(snd_pcm_direct_t *dmix)
 {
        static int shm_sum_discard(snd_pcm_direct_t *dmix);
+       struct shmid_ds buf;
+       int tmpid, err;
        size_t size;
 
        size = dmix->shmptr->s.channels *
               dmix->shmptr->s.buffer_size *
               sizeof(signed int);      
+retryshm:
        dmix->u.dmix.shmid_sum = shmget(dmix->ipc_key + 1, size, IPC_CREAT | 0666);
-       if (dmix->u.dmix.shmid_sum < 0)
-               return -errno;
+       err = -errno;
+       if (dmix->u.dmix.shmid_sum < 0){
+               if (errno == EINVAL)
+               if ((tmpid = shmget(dmix->ipc_key + 1, 0, 0666)) != -1)
+               if (!shmctl(tmpid, IPC_STAT, &buf))
+               if (!buf.shm_nattch) 
+               /* no users so destroy the segment */
+               if (!shmctl(tmpid, IPC_RMID, NULL))
+                   goto retryshm;
+               return err;
+       }
        dmix->u.dmix.sum_buffer = shmat(dmix->u.dmix.shmid_sum, 0, 0);
        if (dmix->u.dmix.sum_buffer == (void *) -1) {
                shm_sum_discard(dmix);
@@ -214,7 +226,7 @@ static void mix_areas1(unsigned int size,
 {
        register signed int sample, old_sample;
 
-       while (size-- > 0) {
+       for (;;) {
                sample = *src;
                old_sample = *sum;
                if (*dst == 0)
@@ -230,6 +242,8 @@ static void mix_areas1(unsigned int size,
                                sample = old_sample;
                        *dst = sample;
                } while (*sum != old_sample);
+               if (!--size)
+                       return;
                ((char *)src) += src_step;
                ((char *)dst) += dst_step;
                ((char *)sum) += sum_step;
@@ -244,7 +258,7 @@ static void mix_areas2(unsigned int size,
 {
        register signed int sample, old_sample;
 
-       while (size-- > 0) {
+       for (;;) {
                sample = *src / 256;
                old_sample = *sum;
                if (*dst == 0)
@@ -260,6 +274,8 @@ static void mix_areas2(unsigned int size,
                                sample = old_sample * 256;
                        *dst = sample;
                } while (*sum != old_sample);
+               if (!--size)
+                       return;
                ((char *)src) += src_step;
                ((char *)dst) += dst_step;
                ((char *)sum) += sum_step;
@@ -366,9 +382,11 @@ static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm, snd_pcm_uframes_t size)
        dmix->slave_appl_ptr %= dmix->shmptr->s.boundary;
        while (size > 0) {
                transfer = appl_ptr + size > pcm->buffer_size ? pcm->buffer_size - appl_ptr : size;
-               transfer = slave_appl_ptr + transfer > dmix->shmptr->s.buffer_size ? dmix->shmptr->s.buffer_size - slave_appl_ptr : transfer;
-               size -= transfer;
+               if ((transfer = slave_appl_ptr + transfer > dmix->shmptr->s.buffer_size ? dmix->shmptr->s.buffer_size - slave_appl_ptr : transfer))
                mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
+               if (transfer >= size)
+                       return;
+               size -= transfer;
                slave_appl_ptr += transfer;
                slave_appl_ptr %= dmix->shmptr->s.buffer_size;
                appl_ptr += transfer;
index 15a8e714daf8d87987234dc3754c20e684fb8a68..e104d2e05f6a7212c2bf054f7f3f5573074cc455 100644 (file)
@@ -51,16 +51,17 @@ static void MIX_AREAS1(unsigned int size,
                "\tmovl %1, %%edi\n"
                "\tmovl %2, %%esi\n"
                "\tmovl %3, %%ebx\n"
+               "\tjmp 2f\n"
+
 
                /*
-                * while (size-- > 0) {
+                * for (;;)
                 */
-               "\tcmpl $0, %0\n"
-               "jz 6f\n"
-
                "\t.p2align 4,,15\n"
-
                "1:"
+               "\tadd %4, %%edi\n"
+               "\tadd %5, %%esi\n"
+               "\tadd %6, %%ebx\n"
 
                /*
                 *   sample = *src;
@@ -69,14 +70,17 @@ static void MIX_AREAS1(unsigned int size,
                 *     sample -= sum_sample;
                 *   xadd(*sum, sample);
                 */
-               "\tmovw $0, %%ax\n"
-               "\tmovw $1, %%cx\n"
+
+               "2:"
+               "\txor %%ax, %%ax\n"
+               "\tmovw %%ax, %%cx\n"
+               "\tincw  %%cx\n"
                "\tmovl (%%ebx), %%edx\n"
                "\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
                "\tmovswl (%%esi), %%ecx\n"
-               "\tjnz 2f\n"
+               "\tjnz 3f\n"
                "\tsubl %%edx, %%ecx\n"
-               "2:"
+               "3:"
                "\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 
                /*
@@ -87,25 +91,22 @@ static void MIX_AREAS1(unsigned int size,
                 *   } while (v != *sum);
                 */
 
-               "3:"
+               "4:"
                "\tmovl (%%ebx), %%ecx\n"
                "\tcmpl $0x7fff,%%ecx\n"
-               "\tjg 4f\n"
+               "\tjg 5f\n"
                "\tcmpl $-0x8000,%%ecx\n"
-               "\tjl 5f\n"
+               "\tjl 6f\n"
                "\tmovw %%cx, (%%edi)\n"
                "\tcmpl %%ecx, (%%ebx)\n"
-               "\tjnz 3b\n"
+               "\tjnz 4b\n"
 
                /*
                 * while (size-- > 0)
                 */
-               "\tadd %4, %%edi\n"
-               "\tadd %5, %%esi\n"
-               "\tadd %6, %%ebx\n"
                "\tdecl %0\n"
-               "\tjnz 1b\n"
-               "\tjmp 6f\n"
+               "\tjz  7f\n"
+               "\tjmp 1b\n"
 
                /*
                 *  sample > 0x7fff
@@ -113,16 +114,13 @@ static void MIX_AREAS1(unsigned int size,
 
                "\t.p2align 4,,15\n"
 
-               "4:"
+               "5:"
                "\tmovw $0x7fff, (%%edi)\n"
                "\tcmpl %%ecx,(%%ebx)\n"
-               "\tjnz 3b\n"
-               "\tadd %4, %%edi\n"
-               "\tadd %5, %%esi\n"
-               "\tadd %6, %%ebx\n"
+               "\tjnz 4b\n"
                "\tdecl %0\n"
                "\tjnz 1b\n"
-               "\tjmp 6f\n"
+               "\tjmp 7f\n"
 
                /*
                 *  sample < -0x8000
@@ -130,18 +128,15 @@ static void MIX_AREAS1(unsigned int size,
 
                "\t.p2align 4,,15\n"
 
-               "5:"
+               "6:"
                "\tmovw $-0x8000, (%%edi)\n"
                "\tcmpl %%ecx, (%%ebx)\n"
-               "\tjnz 3b\n"
-               "\tadd %4, %%edi\n"
-               "\tadd %5, %%esi\n"
-               "\tadd %6, %%ebx\n"
+               "\tjnz 4b\n"
                "\tdecl %0\n"
                "\tjnz 1b\n"
                // "\tjmp 6f\n"
                
-               "6:"
+               "7:"
 
                : /* no output regs */
                : "m" (size), "m" (dst), "m" (src), "m" (sum), "m" (dst_step), "m" (src_step), "m" (sum_step)
@@ -174,17 +169,15 @@ static void MIX_AREAS1_MMX(unsigned int size,
                "\tmovl %1, %%edi\n"
                "\tmovl %2, %%esi\n"
                "\tmovl %3, %%ebx\n"
-
-               /*
-                * while (size-- > 0) {
-                */
-               "\tcmpl $0, %0\n"
-               "jz 6f\n"
+               "\tjmp  2f\n"
 
                "\t.p2align 4,,15\n"
-
                "1:"
+               "\tadd %4, %%edi\n"
+               "\tadd %5, %%esi\n"
+               "\tadd %6, %%ebx\n"
 
+               "2:"
                /*
                 *   sample = *src;
                 *   sum_sample = *sum;
@@ -192,14 +185,15 @@ static void MIX_AREAS1_MMX(unsigned int size,
                 *     sample -= sum_sample;
                 *   xadd(*sum, sample);
                 */
-               "\tmovw $0, %%ax\n"
-               "\tmovw $1, %%cx\n"
+               "\txor  %%ax, %%ax\n"
+               "\tmovw %%ax, %%cx\n"
+               "\tincw %%cx\n"
                "\tmovl (%%ebx), %%edx\n"
                "\t" LOCK_PREFIX "cmpxchgw %%cx, (%%edi)\n"
                "\tmovswl (%%esi), %%ecx\n"
-               "\tjnz 2f\n"
+               "\tjnz 3f\n"
                "\tsubl %%edx, %%ecx\n"
-               "2:"
+               "3:"
                "\t" LOCK_PREFIX "addl %%ecx, (%%ebx)\n"
 
                /*
@@ -210,27 +204,20 @@ static void MIX_AREAS1_MMX(unsigned int size,
                 *   } while (v != *sum);
                 */
 
-               "3:"
+               "4:"
                "\tmovl (%%ebx), %%ecx\n"
                "\tmovd %%ecx, %%mm0\n"
                "\tpackssdw %%mm1, %%mm0\n"
                "\tmovd %%mm0, %%eax\n"
                "\tmovw %%ax, (%%edi)\n"
                "\tcmpl %%ecx, (%%ebx)\n"
-               "\tjnz 3b\n"
+               "\tjnz 4b\n"
 
                /*
                 * while (size-- > 0)
                 */
-               "\tadd %4, %%edi\n"
-               "\tadd %5, %%esi\n"
-               "\tadd %6, %%ebx\n"
                "\tdecl %0\n"
                "\tjnz 1b\n"
-               "\tjmp 6f\n"
-
-               "6:"
-               
                "\temms\n"
 
                : /* no output regs */
@@ -265,12 +252,6 @@ static void MIX_AREAS2(unsigned int size,
                "\tmovl %2, %%esi\n"
                "\tmovl %3, %%ebx\n"
 
-               /*
-                * while (size-- > 0) {
-                */
-               "\tcmpl $0, %0\n"
-               "jz 6f\n"
-
                "\t.p2align 4,,15\n"
 
                "1:"
@@ -334,12 +315,12 @@ static void MIX_AREAS2(unsigned int size,
                /*
                 * while (size-- > 0)
                 */
+               "\tdecl %0\n"
+               "\tjz 6f\n"
                "\tadd %4, %%edi\n"
                "\tadd %5, %%esi\n"
                "\tadd %6, %%ebx\n"
-               "\tdecl %0\n"
-               "\tjnz 1b\n"
-               // "\tjmp 6f\n"
+               "\tjmp 1b\n"
                
                "6:"
                : /* no output regs */
index ba3e7c2a5f8648671a94a029fd9960b514b83f3d..dd30f5c77647c98066526fbd1780419d00240bc1 100644 (file)
@@ -368,6 +368,11 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
                                                SYSERR("shmat failed");
                                                return -errno;
                                        }
+                                       /* automatically remove segment if not used */
+                                       if (shmctl(id, IPC_RMID, NULL) < 0){
+                                               SYSERR("shmctl mark remove failed");
+                                               return -errno;
+                                       }
                                        i->u.shm.area = snd_shm_area_create(id, ptr);
                                        if (i->u.shm.area == NULL) {
                                                SYSERR("snd_shm_area_create failed");
index 53a6533bb3e703ed357f9c41f3410e8df0e6256d..0d7d30bd215deea2ce5bc3fc2b1edbd86340a091 100644 (file)
@@ -56,17 +56,6 @@ struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area)
        return area;
 }
 
-static void _x_destroy(struct snd_shm_area *area)
-{
-       struct shmid_ds buf;
-
-       shmdt(area->ptr);
-       if (shmctl(area->shmid, IPC_STAT, &buf) >= 0) {
-               if (buf.shm_nattch == 0)
-                       shmctl(area->shmid, IPC_RMID, NULL);
-       }
-}
-
 int snd_shm_area_destroy(struct snd_shm_area *area)
 {
        if (area == NULL)
@@ -74,7 +63,7 @@ int snd_shm_area_destroy(struct snd_shm_area *area)
        if (--area->share)
                return 0;
        list_del(&area->list);
-       _x_destroy(area);
+       shmdt(area->ptr);
        free(area);
        return 0;
 }
@@ -88,6 +77,6 @@ void snd_shm_area_destructor(void)
 
        list_for_each(pos, &shm_areas) {
                area = list_entry(pos, struct snd_shm_area, list);
-               _x_destroy(area);
+               shmdt(area->ptr);
        }
 }