Chinaunix首页 | 论坛 | 博客
  • 博客访问: 423632
  • 博文数量: 115
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 393
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-26 12:10
个人简介

踏实做事,认真做人

文章分类

全部博文(115)

文章存档

2017年(1)

2016年(2)

2015年(14)

2014年(63)

2013年(35)

分类:

2014-05-09 11:13:01

原文地址:内核互斥:spin_lock_* 作者:dglwx

互斥手段的选择,不是根据临界区的大小,而是根据临界区的性质,以及 有哪些部分的代码,即哪些内核执行路径来争夺。 
  从严格意义上说,semaphore和spinlock_XXX属于不同层次的互斥手段,前者的 实现有赖于后者,这有点象HTTP和TCP的关系,都是协议,但层次是不同的。 
  先说semaphore,它是进程级的,用于多个进程之间对资源的互斥,虽然也是在 内核中,但是该内核执行路径是以进程的身份,代表进程来争夺资源的。如果 竞争不上,会有context switch,进程可以去sleep,但CPU不会停,会接着运行 其他的执行路径。从概念上说,这和单CPU或多CPU没有直接的关系,只是在 semaphore本身的实现上,为了保证semaphore结构存取的原子性,在多CPU中需要spinlock来互斥。 
  在内核中,更多的是要保持内核各个执行路径之间的数据访问互斥,这是最基本的互斥问题,即保持数据修改的原子性。semaphore的实现,也要依赖这个。在单CPU中,主要是中断和bottom_half的问题,因此,开关中断就可以了。在多CPU中,又加上了其他CPU的干扰,因此需要spinlock来帮助。这两个部分结合起来,就形成了spinlock_XXX。它的特点是,一旦CPU进入了spinlock_XXX,它就不会干别的,而是一直空转,直到锁定成功为止。因此,这就决定了被spinlock_XXX锁住的临界区不能停,更不能context switch,要存取完数据后赶快出来,以便其他的在空转的执行路径能够获得spinlock。这也是spinlock的原则所在。如果当前执行路径一定要进行context switch,那就要在schedule()之前释放spinlock,否则,容易死锁。因为在中断和bh中,没有context,无法进行context switch,只能空转等待spinlock,你context switch走了,谁知道猴年马月才能回来。 
  因为spinlock的原意和目的就是保证数据修改的原子性,因此也没有理由在spinlock 锁住的临界区中停留。 
  spinlock_XXX有很多形式,有 
  spin_lock()/spin_unlock(), 
  spin_lock_irq()/spin_unlock_irq(), 
  spin_lock_irqsave/spin_unlock_irqrestore() 
  spin_lock_bh()/spin_unlock_bh() 
  local_irq_disable/local_irq_enable 
  local_bh_disable/local_bh_enable 
  那么,在什么情况下具体用哪个呢?这要看是在什么内核执行路径中,以及要与哪些内核执行路径相互斥。我们知道,内核中的执行路径主要有: 
  1 用户进程的内核态,此时有进程context,主要是代表进程在执行系统调用 等。 
  2 中断或者异常或者自陷等,从概念上说,此时没有进程context,不能进行 
  context switch。 
  3 bottom_half,从概念上说,此时也没有进程context。 
  4 同时,相同的执行路径还可能在其他的CPU上运行。 
  这样,考虑这四个方面的因素,通过判断我们要互斥的数据会被这四个因素中 
  的哪几个来存取,就可以决定具体使用哪种形式的spinlock。如果只要和其他CPU互斥,就要用spin_lock/spin_unlock,如果要和irq及其他CPU互斥,就要用 
  spin_lock_irq/spin_unlock_irq,如果既要和irq及其他CPU互斥,又要保存EFLAG的状态,就要用spin_lock_irqsave/spin_unlock_irqrestore,如果要和bh及其他CPU互斥,就要用spin_lock_bh/spin_unlock_bh,如果不需要和其他CPU互斥,只要和irq互斥,则用local_irq_disable/local_irq_enable, 
  如果不需要和其他CPU互斥,只要和bh互斥,则用local_bh_disable/local_bh_enable, 
  等等。值得指出的是,对同一个数据的互斥,在不同的内核执行路径中, 
阅读(609) | 评论(0) | 转发(0) |
0

上一篇:list.h

下一篇:*arm中R0-R15寄存器的作用

给主人留下些什么吧!~~