Linux下无效唤醒的应用

之前看过百度文库中一篇文章“Linux进程的睡眠和唤醒”,但是不是特别理解。

http://wenku.baidu.com/link?url=nXPCC19-zZWPU-ccwnO4ho-6zEuHsCdRn-56gJNbNGN49bjPt8qYuOa6qSI2NCb1s1coom2iob6N_7axaQxl8oxhVDuCznuMu0VfjnHNJ3u

今天看到mtdblock.c文件中的代码,才懂得其中的奥妙。

static void erase_callback(struct erase_info *done)

{
wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
wake_up(wait_q);
}


static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf)
{
struct erase_info erase;
DECLARE_WAITQUEUE(wait, current);
wait_queue_head_t wait_q;
size_t retlen;
int ret;

/*
* First, let's erase the flash block.
*/


init_waitqueue_head(&wait_q);
erase.mtd = mtd;
erase.callback = erase_callback;
erase.addr = pos;
erase.len = len;
erase.priv = (u_long)&wait_q;


set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wait_q, &wait);



ret = mtd_erase(mtd, &erase);
if (ret) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&wait_q, &wait);

printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "    "on \"%s\" failed\n",
pos, len, mtd->name);
return ret;
}


schedule();  /* Wait for erase to finish. */
remove_wait_queue(&wait_q, &wait);


/*
* Next, write the data to flash.
*/
....

}

猛地一看代码确实不理解,一会INTERRUPT一会RUNNING。

深入分析,其实就是避免无效唤醒的策略。

首先调用

DECLARE_WAITQUEUE()

创建一

个等待队列的项,然后调用

add_wait_queue()

把自己加入到等待队列中,并且将进程的状态设置为

TASK_INTERRUPTIBLE

或者

TASK_INTERRUPTIBLE

。然后循环检查条件是否为真:如果是的话就没有必要睡眠,如果条件不为真,就调用

schedule()

。当进程检查

的条件满足后,进程又将自己设置为

TASK_RUNNING 

并调用

remove_wait_queue()

将自己移出等待队列。

 

从上面可以看到,

Linux

的内核代码维护者也是在进程检查条件之前就设置进程的状态为睡眠状态,

 

然后才循环检查条件。如果在进程开始睡眠之前条件就已经达成了,那么循环会退出并用

set_current_state()

将自己的状态设置为

就绪,这

具体步骤如下:

1. 首先调用DECLARE_WAITQUEUE()创建一个等待队列的项

2. 调用add_wait_queue()把自己加入到等待队列中,并且将进程的状态设置为TASK_INTERRUPTIBLE或者TASK_INTERRUPTIBLE。

3. 检查条件是否为真:如果是的话就没有必要睡眠,进程又将自己设置为TASK_RUNNING 并调用remove_wait_queue()将自己移出等待队列。

4. 如果条件不为真,就调用schedule()。等待erase_callback函数执行唤醒自己。


在这里因为考虑到erase的时间过长,所以考虑到了进程调度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值