您的位置:首页 > 大数据 > 人工智能

等待队列实例 wait_for_avail_min

2011-08-10 13:58 274 查看
static int wait_for_avail_min(struct snd_pcm_substream *substream,

snd_pcm_uframes_t *availp)

{

struct snd_pcm_runtime *runtime = substream->runtime;

int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;

wait_queue_t wait; //定义一个等待队列

int err = 0;

snd_pcm_uframes_t avail = 0;

long tout;

init_waitqueue_entry(&wait, current); //动态初始化一个等待队列入口项,将其和当前进程关联起来,以便唤醒当前进程

add_wait_queue(&runtime->tsleep, &wait); //向等待队列头中添加等待队列

for (;;) {

if (signal_pending(current)) {// 检查当前进程是否有待处理的信号,返回不为0表示有信号需要处理。

err = -ERESTARTSYS;

/*-ERESTARTSYS表示信号函数处理完毕后重新执行信号函数前的某个系统调用。

也就是说,如果信号函数前有发生系统调用,在调度用户信号函数之前,内核会检查系统调用的返回值,看看是不是因为这个信号而中断了系统调用.

如果返回值-ERESTARTSYS,并且当前调度的信号具备-ERESTARTSYS属性,系统就会在用户信号函数返回之后再执行该系统调用。*/
break;

}

set_current_state(TASK_INTERRUPTIBLE); //设置当前进程的状态为可中断的。当满足“条件达成”、“收到信号”之一时就被唤醒

snd_pcm_stream_unlock_irq(substream);

tout = schedule_timeout(msecs_to_jiffies(10000));
//在指定的时间内没有获得等待的资源就返回

snd_pcm_stream_lock_irq(substream);

switch (runtime->status->state) {

case SNDRV_PCM_STATE_SUSPENDED:

err = -ESTRPIPE;

goto _endloop;

case SNDRV_PCM_STATE_XRUN:

err = -EPIPE;

goto _endloop;

case SNDRV_PCM_STATE_DRAINING:

if (is_playback)

err = -EPIPE;

else

avail = 0; /* indicate draining */

goto _endloop;

case SNDRV_PCM_STATE_OPEN:

case SNDRV_PCM_STATE_SETUP:

case SNDRV_PCM_STATE_DISCONNECTED:

err = -EBADFD;

goto _endloop;

}
//时间到被唤醒,没有收到信号

if (!tout) { snd_printd("%s write error (DMA or IRQ trouble?)\n",

is_playback ? "playback" : "capture");

err = -EIO;

break;

}

//收到信号被唤醒

if (is_playback)

avail = snd_pcm_playback_avail(runtime);

else

avail = snd_pcm_capture_avail(runtime);

if (avail >= runtime->control->avail_min)

break;

}

_endloop:

remove_wait_queue(&runtime->tsleep, &wait); //在等待的资源或条件满足时,进程被唤醒,将等待队列从等待头中删除

*availp = avail;

return err;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: