您的位置:首页 > 其它

JOS大内核锁

2015-11-03 22:29 309 查看
JOSlab4里面,采用了SMT的操作系统,所以可能存在两个CPU同时进入内核态,虽然CPU之间的内核栈,但是多核同步可能还是会出现问题,所以JOS采用大内核锁来锁住整个内核,使得每次只有一个CPU会进入内核,另外的CPU如果申请进入内核态,是进不去的。

    首先,看一下内核锁的实现方法:

  

struct spinlock {
unsigned locked;
};

/***************************************/
spin_lock(struct spinlock *lk)
{

while (xchg(&lk->locked, 1) != 0)
asm volatile ("pause");
}

/************************************************/
void
spin_unlock(struct spinlock *lk)
{
xchg(&lk->locked, 0);
}


  总共只有三个不同的内容,一个变量,还有就是上锁和解锁。

  首先看xchg操作,xchg操作是一个原子操作,它的作用就是交换两个参数,并且返回第一个参数原来的值。

  现在看下上锁过程,假设CPU0进入内核,首先要进行上锁操作,

  xchg(&lk->locked, 1)

  

  CPU0会执行上面的原子操作,并且返回lk->locked的原来的值,如果原来的值是0,则进入内核,并且内核也被上锁,即lk->locked被赋值为1,当其他CPU要进入的时候,lk->locked一直是1,此时,会执行:

   asm volatile (“pause”);

   pause指令:

  

Improves the performance of spin-wait loops. When executing a “spin-wait loop,” a Pentium 4 or Intel Xeon processor suffers a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops.

An additional fucntion of the PAUSE instruction is to reduce the power consumed by a Pentium 4 processor while executing a spin loop.

所以,用pause可以让CPU知道接下来的指令是用来自旋等待,就不用做memory reorder了,cache也不用废除了(cache是很宝贵的资源,进程切换的一个重要资源房费就是会导致cache失效,从而导致缓存不命中的问题)。而且附加的功能——减少能耗。

所以用pause就是提醒CPU接下来的指令是自旋等待,什么都不用干,然后CPU一直查询lk->locked的值,直到它的值变为了0,。

2.解锁

解锁就比较简单了,直接把lk->locked变成0就可以了。

  所以,总的来说,JOS用了一个简单的自旋锁来当成一个大的内核锁,这里的内核锁实现是用xchg原子操作了实现的。总体来说,这个方法的优点就是实现简单,而且绝对不会出错。缺点也很明显,效率太低了,估计CPU会有很多时间浪费在等待上面。

  所以后来的内核的方法,主要采用的是在关键资源上面加锁,而不是在整个内核加锁,这样效率就可以大大的提高,但是相对的实现的难度也加大了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  操作系统 内核 多核