您的位置:首页 > 运维架构 > Linux

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

2013-05-16 16:16 579 查看
此为部分内核代码。

应用程序的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;

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;

*}

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;

*}

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