Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72523
  • 博文数量: 11
  • 博客积分: 395
  • 博客等级: 一等列兵
  • 技术积分: 181
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 18:29
文章分类

全部博文(11)

文章存档

2011年(7)

2010年(2)

2009年(2)

我的朋友

分类: LINUX

2011-07-15 16:30:54

1 等待队列的使用

DECLARE_WAITQUEUE(wait, current);

#define __WAITQUEUE_INITIALIZER(name, tsk) {                \
    .private    = tsk,                        \
    .func        = default_wake_function,            \
    .task_list    = { NULL, NULL } }

#define DECLARE_WAITQUEUE(name, tsk)                    \
    wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)


一目了然,给wait这个等待队列赋值,private用来表示被唤醒的进程,这里current代表了本进程, 而func是被唤醒时调用的回调函数, 唤醒private!

add_wait_queue(w_wait, wait);
将wait加入到等待队列w_wait中, 被唤醒时遍历w_wait队列!

wake_up(w_wait)
唤醒w_wait, 遍历队列中的wait, 调用wait的func来唤醒private

所以用法为
task 1
    DECLARE_WAITQUEUE(wait, current);
    add_wait_queue(w_wait, wait);
    __set_current_state(TASK_INTERRUPTIBLE);
    schedule();
    //task1 进程休眠
    ................//唤醒后从这儿执行
task 2 //唤醒task1
   wake_up(w_wait);


2 poll_wait使用
  主要用于非阻塞访问时应用层select的调用
  驱动实现为
  down(&dev->sem);

  poll_wait(filp, &dev->r_wait, wait);
  poll_wait(filp, &dev->w_wait, wait);
  /*fifo非空*/
  if (dev->current_len != 0)
  {
    mask |= POLLIN | POLLRDNORM;
  }
  /*fifo非满*/
  if (dev->current_len != GLOBALFIFO_SIZE)
  {
    mask |= POLLOUT | POLLWRNORM;
  }

  up(&dev->sem);

  和do_select配合使用

static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
    if (p && wait_address)
        p->qproc(filp, wait_address, p); //是在do_select中的poll_init_wait中为__pollwait
}

  /* Add a new entry */
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
                poll_table *p)
{
    struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt);
    struct poll_table_entry *entry = poll_get_entry(pwq);
    if (!entry)
        return;
    get_file(filp);
    entry->filp = filp;
    entry->wait_address = wait_address;
    entry->key = p->key;
    init_waitqueue_func_entry(&entry->wait, pollwake);
    entry->wait.private = pwq;
   
add_wait_queue(wait_address, &entry->wait); // 把p中的entry->wait加入到等待队列
}

void poll_initwait(struct poll_wqueues *pwq)
{
    init_poll_funcptr(&pwq->pt, __pollwait);
    pwq->polling_task = current;
    pwq->triggered = 0;
    pwq->error = 0;
    pwq->table = NULL;
    pwq->inline_index = 0;
}

会在其他task唤醒 然后返回给do_select; do_select实现休眠等待唤醒和select中的延时!

阅读(4403) | 评论(0) | 转发(1) |
1

上一篇:最近...

下一篇:kill_fasync及fasync_helper

给主人留下些什么吧!~~