POLL机制分析(韦东山的视频总结及针对linux-2.6.30.4)

此为部分内核代码。

应用程序的poll   ->  sys_poll  ->  do_sys_poll   ->   (poll_initwait,和do_poll)

应用程序的部分代码:

int main(int argc,char **argv){

        int fd;
        int val=1;
        unsigned char key_val;
        int ret;
        struct pollfd fds[1];//在poll.h中定义
        fd=open("/dev/buttons",O_RDWR);
        if(fd<0)
                printf("can't open!\n");
        fds[0].fd=fd;
        fds[0].events = POLLIN;      //POLLIN 不阻塞地可读除高优先级外的数据

        while(1){

/* int poll (struct pollfd fdarry[ ],nfds_t nfds,int timeout); nfds是数组元素数 ,timeout 等待的毫秒数*/

            ret = poll(fds,1,5000);     
            if(ret == 0) {
                   printf("time out\n");
             }
           else{
                  read(fd,&key_val,1);
                  printf("key_val = 0x%x\n",key_val);//驱动程序中使用的是十六进制,这里%x输出
           }
      }
      return 0;

}

驱动程序里的poll函数:

static unsigned  forth_drv_poll(struct file *file, poll_table *wait)
{
unsigned int mask=0;
poll_wait(file ,&button_waitq,wait); //不会休眠,挂载到队列

if(ev_press)       //ev_press =1说明有中断产生,mask返回非零值,

mask |= POLLIN ;  //不阻塞地可读除高优先级外的数据
return mask;
}


内核框架:

出现两次函数的,下面的是调用;


do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,struct timespec *end_time)

{

  /*
  * Structures and helpers for sys_poll/sys_poll
  */

struct poll_wqueues table;
struct poll_wqueues *pwd=&table;

int  fdcount;

  1. poll_initwait(pwq);//初始化;

/*把poll_initwait(pwq)展开

 *poll_initwait(pwq)

 *{
*pwq->polling_task = current;
*pwq->error = 0;
*pwq->table = NULL;

*pwq->inline_index = 0;

  * init_poll_funcptr(&pwq->pt, __pollwait);

 *init_poll_funcptr(poll_table *pt, __pollwait){

 *   pt->qproc = __pollwait;

 *}

 *}

 
 *结果为table.pt.gbroc=_pollwait
 *   table.error = 0;
 *        table.table = NULL;
 *   polling_task = current;

 *}

  1. fdcount = do_poll(nfds, head, &table, end_time);
/* do_poll(nfds, head, &table, end_time);展开

 *do_poll(nfds, head, &table, end_time)

 *{
 *    for (;;) {

 *         struct poll_list *walk;

 *    poll_table* pt = &table->pt;

 *         for (walk = head; walk != NULL; walk = walk->next) {

* struct pollfd * pfd, * pfd_end;
* pfd = walk->entries;
* pfd_end = pfd + walk->len;

 *         for (; pfd != pfd_end; pfd++) {

 *        if (do_pollfd(pfd, pt)) { 

/*

 *   do_pollfd(pfd, pt)展开,

 *  mask = file->f_op->poll(file,&table->pt);调用驱动poll函数,

* pfd->revents = mask;       

* return mask;

      *     把驱动程序的poll函数展开:   

* forth_drv_poll(file,&table->pt ){

* poll_wait(file ,&button_waitq,&table->pt); 

                  *}                     

  *poll_wait(file ,&button_waitq,&table->pt);展开

  *           &table->ptwait->qproc(file,&button_waitq ,&table->pt);   

  *由 上面初始化时 : table.pt.gbroc=_pollwait 

  *相当于_pollwait(file,&button_waitq , &table->pt);   //挂载到队列,

 */

            count++;          //如果驱动程序poll返回非零,count自加                   

                    pt = NULL;
 *}
 *}

 *}

 *}

 *if (count || timed_out)
 *break;
 *//不满足,休眠
 *if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
 *   timed_out = 1;

 *}

}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值