2022年linux..poll系统调用源码分析 .pdf
《2022年linux..poll系统调用源码分析 .pdf》由会员分享,可在线阅读,更多相关《2022年linux..poll系统调用源码分析 .pdf(8页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、linux2.6.9 poll 系统调用源码分析(2011-03-27 21:27:22)转载标签:杂谈分类:EPOLL 1、涉及到的数据结构typedef void(*poll_queue_proc)(struct file*,wait_queue_head_t*,struct poll_table_struct*);/声明回调函数类型,内核中不同的模块实现不同的回调函数(但接口统一),以提供给驱动程序调用。typedef struct poll_table_struct poll_queue_proc qproc;poll_table;/对上述类型的封装,便于以后的扩充struct pol
2、l_table_page struct poll_table_page*next;/指向下一个元素struct poll_table_entry*entry;/保存 entries 中的当前元素struct poll_table_entry entries0;/保存 poll_table_entry 元素;/内核中用来保存套接字的数据结构struct poll_table_entry struct file*filp;wait_queue_t wait;wait_queue_head_t*wait_address;/一个句柄对应的内核结构struct poll_wqueues poll_tab
3、le pt;struct poll_table_page*table;int error;/用于等待函数的结构struct pollfd int fd;short events;short revents;/用户态的句柄struct poll_list 名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 8 页 -struct poll_list*next;int len;struct pollfd entries0;/将用户态的句柄拷贝到内核时使用的结构2、对应函数源码分析1、sys_poll asmlinkage long sys_poll(struct pollfd _user
4、*ufds,unsigned int nfds,long timeout)struct poll_wqueues table;int fdcount,err;unsigned int i;struct poll_list*head;struct poll_list*walk;检测句柄数目用户传入的句柄数目不能超过进程所支持的最大句柄数。if(nfds current-files-max_fdset&nfds OPEN_MAX)return-EINV AL;if(timeout)if(unsigned long)timeout POLLFD_PER_PAGE?POLLFD_PER_PAGE:i)
5、,GFP_KERNEL);if(pp=NULL)goto out_fds;pp-next=NULL;pp-len=(iPOLLFD_PER_PAGE?POLLFD_PER_PAGE:i);if(head=NULL)head=pp;else walk-next=pp;walk=pp;if(copy_from_user(pp-entries,ufds+nfds-i,sizeof(struct pollfd)*pp-len)err=-EFAULT;goto out_fds;i-=pp-len;调用 do_poll,检测是否有句柄就绪fdcount=do_poll(nfds,head,&table,t
6、imeout);将 revents 字段拷贝到用户空间下面的 while 循环就是将do_poll 之后的 revents 字段拷贝到用户空间,当句柄数很多时,这也是 poll 系统调用的性能瓶颈。walk=head;err=-EFAULT;while(walk!=NULL)struct pollfd*fds=walk-entries;int j;for(j=0;j len;j+,ufds+)if(_put_user(fdsj.revents,&ufds-revents)goto out_fds;walk=walk-next;名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 8 页
7、 -err=fdcount;if(!fdcount&signal_pending(current)err=-EINTR;释放分配的空间out_fds:walk=head;while(walk!=NULL)struct poll_list*pp=walk-next;kfree(walk);walk=pp;poll_freewait(&table);return err;2、poll_initwait 设定 poll_table 对应回调函数很明显,poll_initwait的主要动作就是把table 变量的成员poll_table 对应的回调函数置为_pollwait。这个 _pollwait不
8、仅是poll 系统调用需要,select 系统调用也一样是用这个_pollwait,说白了,这(_pollwait)是个操作系统的异步操作的“御用”回调函数。void poll_initwait(struct poll_wqueues*pwq)init_poll_funcptr(&pwq-pt,_pollwait);/&(pwq-pt)-qproc=_pollwait;pwq-error=0;pwq-table=NULL;3、do_poll static int do_poll(unsigned int nfds,struct poll_list*list,struct poll_wqueue
9、s*wait,long timeout)int count=0;poll_table*pt=&wait-pt;if(!timeout)pt=NULL;for(;)struct poll_list*walk;set_current_state(TASK_INTERRUPTIBLE);walk=list;while(walk!=NULL)DO_POLLFD 调用名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 8 页 -对用户传入的每一个句柄,调用 do_pollfd 设定在本句柄上等待的事件发生时需要执行的回调函数,同时检测本句柄上等待的事件是否就绪,如果就绪则递增count。当用户
10、传入的fd 很多时(比如1000 个),对 do_pollfd 就会调用很多次,poll 效率瓶颈的另一原因就在这里do_pollfd(walk-len,walk-entries,&pt,&count);walk=walk-next;pt=NULL;返回当有等待的时间就绪,设定的时间超时或者本进程收到信号则跳出循环,返回。if(count|!timeout|signal_pending(current)break;count=wait-error;if(count)break;休眠让 current 挂起,别的进程跑,timeout 到了以后再回来运行current,或者是在current 等
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年linux.poll系统调用源码分析 2022 linux poll 系统 调用 源码 分析
限制150内