linux2.6.38 linux内核poll机制解析

预备知识:

__VA_ARGS__

首先来解释一下SYSCALL_DEFINEx 中的x表示上层应用函数的参数个数,比如select()函数有5个参数,因此会对应到SYSCALL_DEFINE5。sname表示的就是上层应用程序中函数的名字,如select。


下面我们来分析SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
long, timeout_msecs)

SYSCALL_DEFINE3是个宏,在/include/linux/syscalls.h 中定义了如下的宏:

[plain]  view plain copy
  1. #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
    #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
    #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
    #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
    #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)

因此可分解得到如下代码:

SYSCALL_DEFINEx(3, _##poll, __VA_ARGS__)

SYSCALL_DEFINEx又定义为如下宏:
[plain]  view plain copy
  1. #define SYSCALL_DEFINEx(x, name, ...)\
    asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))




而__SYSCALL_DEFINEx又定义如下:
[plain]  view plain copy
  1. #define __SYSCALL_DEFINEx(x, name, ...)                 \  
  2.     asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))  


由此再分解为如下:
asmlinkage long sys##_##select(__SC_DECL##3(__VA_ARGS__))

即asmlinkage long sys_select(__SC_DECL3(__VA_ARGS__))

这样结果已经开始清晰了,对于__SC_DECL3也是宏,如下:
[plain]  view plain copy
  1. #define __SC_DECL1(t1, a1)  t1 a1  
  2. #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)  
  3. #define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__)  
  4. #define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__)  
  5. #define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__)  
  6. #define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__)  
__SC_DECL5实际为嵌套宏,最后可分解为:t3 a3,t2 a2,t1 a1 

struct pollfd __user *, ufds, unsigned int, nfds,
long, timeout_msecs

也就是  struct pollfd __user *, ufds, unsigned int, nfds,long, timeout_msecs


最后,我们就清楚的了解了系统调用的过程,其他系统调用同理



poll调用过程:

app:poll

kernerl:sys_poll(struct pollfd __user *ufds, unsigned int nfds,long timeout);

即:SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,long, timeout_msecs)

do_sys_poll(ufds, nfds, to)

do_sys_poll();

poll_initwait(&table);

init_poll_funcptr(&pwq->pt, __pollwait); 即init_poll_funcptr(&table->pt, __pollwait);

pt->qproc = qproc;table->pt->qproc=__pollwait;

  fdcount = do_poll(nfds, head,&table, timeout);

do_pollfd(pfd, pt)

          if(file->f_op && file->f_op->poll)

                      mask= file->f_op->poll(file, pwait); //与驱动里面的poll函数相联系

poll_wait(file, &button_waitq, wait); 即 poll_wait(file, &button_waitq,pwait);

p->qproc(filp, wait_address, p); 即:__pollwaitfile,&button_waitq,table->pt)//把当期进//程加进等 //待队列;

schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS) 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值