Linux 内核信号量down up函数分析及linux内核设备驱动的注册和卸载

内核驱动开发中遇到下面某设备卸载函数,对其中up/down调用机制不清楚,找了资料记录总结: 

void  device_unregister(struct device *rd)
{
    if (!rd)
        return;
    down(&rd->semaphore);
    rd->rops = NULL;
    up(&rd->semaphore);
    if (rd->cache_inited)
        cache_release(rd);
    device_unregister(&rd->dev);
}
EXPORT_SYMBOL(device_unregister);

/

DOWN操作:linux内核中,对信号量的DOWN操作有如下几种:

    void down(struct semaphore *sem); //不可中断
    int down_interruptible(struct semaphore *sem);//可中断
    int down_killable(struct semaphore *sem);//睡眠的进程可以因为受到致命信号而被唤醒,中断获取信号量的操作。
    int down_trylock(struct semaphore *sem);//试图获取信号量,若无法获得则直接返回1而不睡眠。返回0则 表示获取到了信号量
    int down_timeout(struct semaphore *sem,long jiffies);//表示睡眠时间是有限制的,如果在jiffies指明的时间到期时仍然无法获得信号量,则将返回错误码。

在以上四种函数中,驱动程序使用的最频繁的就是down_interruptible函数,以下将对该函数进行分析。

down_interruptible函数的定义如下:

    int down_interruptible(struct semaphore *sem)
    {
           unsigned long flags;
           int result = 0;
           spin_lock_irqsave(&sem->lock,flags);
           if (likely(sem->count> 0))
                  sem->count--;
           else
                  result =__down_interruptible(sem);
           spin_unlock_irqrestore(&sem->lock,flags);
           return result;
    }

函数分析:函数首先通过spin_lock_irqsave的调用来保证对sem->count操作的原子性。如果count>0,表示当前进程可以获得信号量,将count的值减1然后退出。如果count不大于0,表明当前进程无法获取信号量,则调用__down_interruptible,后者会继续调用__down_common。

__down_common 函数定义如下:

    static inline int __sched __down_common(struct semaphore *sem, longstate,
                                                            longtimeout)
    {
           struct task_struct *task= current;
           struct semaphore_waiterwaiter;
           list_add_tail(&waiter.list,&sem->wait_list);
           waiter.task = task;
           waiter.up = 0;
           for (;;) {
                  if(signal_pending_state(state, task))
                         gotointerrupted;
                  if (timeout <=0)
                         gototimed_out;
                  __set_task_state(task,state);
                  spin_unlock_irq(&sem->lock);
                  timeout =

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值