查找出现“wait_event_timeout failed for session X”的原因

原创 2012年03月29日 20:42:18

查找出现“wait_event_timeout failed for session X”的原因

1 Audio相关代码文件

Sound/soc/msm/qdsp6/q6asm.c

Sound/soc/msm/qdsp6/q6adm.c

Sound/soc/msm/qdsp6/q6afe.c

Sound/soc/msm/msm8x60-dai.c

Sound/soc/msm/msm8x60.c

Sound/soc/msm/msm8x60-pcm.c

Sound/soc/msm/snd-soc-lpass-dma.c

Sound/soc/codec/wnc/wnc/wnc_wm8737.c

Arch/arm/mach-msm/qdsp6v2/pcm_out.c

Arch/arm/mach-msm/qdsp6v2/pcm_in.c

Hardware/qcom/media/audio/msm8660/

 

2Arch/arm/mach-msm/qdsp6v2/pcm_out.c

static ssize_t pcm_out_write(struct file *file, const char __user *buf,

                                               size_t count, loff_t *pos)

{

。。。。。。

                   rc = wait_event_timeout(pcm->write_wait,

                                     (atomic_read(&pcm->out_count) ||

                                     atomic_read(&pcm->out_stopped)), 1 * HZ );

                   if (!rc) {

                            pr_err("%s: wait_event_timeout failed for session %d\n",

                                     __func__, pcm->ac->session);

                            goto fail;

                   }

。。。。。。

rc = q6asm_write(pcm->ac, xfer, 0, 0, NO_TIMESTAMP);

。。。。。。

                   atomic_dec(&pcm->out_count);

。。。。。。

}

 

pcm->out_count为目前闲着的buffer个数。向底层每写入1buffer数据,out_count1.

 

3  pcm_out_cb()为回调函数,当底层写完数据后进入,out_count1.

void pcm_out_cb(uint32_t opcode, uint32_t token,

                            uint32_t *payload, void *priv)

{

         struct pcm *pcm = (struct pcm *) priv;

         unsigned long flags;

         spin_lock_irqsave(&pcm->dsp_lock, flags);

         switch (opcode) {

         case ASM_DATA_EVENT_WRITE_DONE:

                   atomic_inc(&pcm->out_count);

                   wake_up(&pcm->write_wait);

                   break;

         default:

                   break;

         }

         spin_unlock_irqrestore(&pcm->dsp_lock, flags);

}

4 atomic_read(&pcm->out_count)等于0时,证明没有闲着的buffer,等1秒钟,仍然没有可以用的buffer,则打印“wait_event_timeout failed for session X”,向上返回0.

若底层有问题,数据传不下去,则会不停的报“wait_event_timeout failed for session X”,若只报一次,证明下次就正常了,所以问题不大。

 

5 HAL层向下写入的过程:

ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)

{

if (mStandby) {

        // open driver

        status = ::open("/dev/msm_pcm_out", O_WRONLY/*O_RDWR*/);

    // configuration

        status = ioctl(mFd, AUDIO_GET_CONFIG, &config);

        config.channel_count = AudioSystem::popCount(channels());

        config.sample_rate = sampleRate();

        config.buffer_size = bufferSize();

        config.buffer_count = AUDIO_HW_NUM_OUT_BUF;

        config.codec_type = CODEC_TYPE_PCM;

        status = ioctl(mFd, AUDIO_SET_CONFIG, &config);

        // fill 2 buffers before AUDIO_START

        mStartCount = AUDIO_HW_NUM_OUT_BUF;

        mStandby = false;

    }

    while (count) {

        ssize_t written = ::write(mFd, p, count);

        if (written > 0) {

            count -= written;

            p += written;

        } else {

            if (errno != EAGAIN) return written;

            mRetryCount++;

            LOGW("EAGAIN - retry");

        }

    }

    // start audio after we fill 2 buffers

    if (mStartCount) {

        if (--mStartCount == 0) {

            if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) {

                LOGE("AUDIO_GET_SESSION_ID failed*********");

                return 0;

            }

            ioctl(mFd, AUDIO_START, 0);

        }

    }

return bytes;

}

通过ioctl(mFd, AUDIO_SET_CONFIG, &config);将配置传下去。(Buffersize=4800buffercount=2)。

先写入两个buffer,再ioctl(mFd, AUDIO_START, 0);然后再继续写。底层接到AUDIO_START命令后,会设置音量等。猜想这样做可能是为了消除pop音。

 6 音频设备

输入(1)遥控器 usb声卡 pcm1804_mic_tx

      (2)卡拉OK CODEC

输出 HDMI hdmi_stereo_rx

相关文章推荐

linux内核中等待队列(wait_event,wake_up...)

2012-12-25 15:09:57 分类: LINUX 根据内核3.1.6版本源码、书籍和网上资料,对几个函数进行分析        介绍这几个函数,不得不先介绍...

_wait_event 具体实现过程

来自:http://www.linuxforum.net/forum/showthreaded.php?Board=linuxK&Number=572220 是不是当前进程要等待某个conditio...

linux 等待队列 wait_event wake_up等函数讲解

源自:http://www.yiyon.net/index.php/archives/120 一、等待队列        (一)数据结构        等待队列结构如下,因为每个等待...

Linux内核:通过wait_event和wake_up内在机制分析等待队列

等待队列在linux内核中,等待队列是一个非常重要的概念,也是一个非常重要的机制。我们会在很多函数当中用到等待队列的知识,例如completion机制、wait_event机制等等。在解释这些机制之前...

linux内核中等待队列 (函数wait_event与wake_up)

根据内核3.1.6版本源码、书籍和网上资料,对几个函数进行分析        介绍这几个函数,不得不先介绍等待队列wait_queue_head_t与完成量completion。        等待队...

linux内核中等待队列 (函数wait_event与wake_up)

根据内核3.1.6版本源码、书籍和网上资料,对几个函数进行分析        介绍这几个函数,不得不先介绍等待队列wait_queue_head_t与完成量completion。        等...

linux内核中等待队列(wait_event,wake_up...)

wait_event,wake_up
  • Fybon
  • Fybon
  • 2017年03月22日 17:53
  • 955

linux内核--wait_event_interruptible_timeout()函数分析

网上有关于此函数的分析,但大都是同一篇文章转载来转载去,没有进一步的分析。做个小结:了解函数功能,除了直接看代码逻辑,最有效的当是注释内容了。 如下:函数原型:wait_event_interrup...

【Linux设备驱动程序(第三版)】----延迟:超时(wait_event_interruptible_timeout)

【Linux设备驱动程序(第三版)】----延迟:超时(wait_event_interruptible_timeout)jit.c#include #include #include #...

wait_event_interruptible_timeout和schedule_timeout的区别

上面提到的采用schedule()函数的解决方法之所以还不是最佳的,其根本原因在于调用schedule()函数的进程依然处于CPU的运行队列中。为了解决这个问题,此时应该能想到内核提供的另外一种可供设...
  • jzzjsy
  • jzzjsy
  • 2013年11月19日 15:02
  • 1350
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:查找出现“wait_event_timeout failed for session X”的原因
举报原因:
原因补充:

(最多只允许输入30个字)