码迷,mamicode.com
首页 > 其他好文 > 详细

JOS中 "spinlock" 的实现

时间:2015-02-19 16:21:00      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:operating system   kernel   

JOS中  "spinlock" 的实现


  1. In software engineering, a spinlock is a lock which causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking if the lock is available. Since the thread remains active but is not performing a useful task, the use of such a lock is a kind of busy waiting.
                                                                                                                                                       -- from wikipedia

XCHG instruction Swaps data between two registers or a register and memory location.

LOCK汇编指令用于封锁总线. 

static inline uint32_t
xchg(volatile uint32_t *addr, uint32_t newval)
{
	uint32_t result;

	// The + in "+m" denotes a read-modify-write operand.
	asm volatile("lock; xchgl %0, %1" :
			"+m" (*addr), "=a" (result) :
			"1" (newval) :
			"cc");
	return result;
}
每次都会返回addr指向地址处原来的值.



于是乎,在JOS中,spinlock的实现如下:

./kern/spinlock.h 这里利用结构体struct spinlock来抽象封装spinlock.

实质上,spinlock是个全局变量.这里具体的就是./kern/spinlock.h 中的全局变量结构体 

extern struct spinlock kernel_lock.

// Mutual exclusion lock.
struct spinlock {
	unsigned locked;       // Is the lock held?
};

void __spin_initlock(struct spinlock *lk, char *name);
void spin_lock(struct spinlock *lk);
void spin_unlock(struct spinlock *lk);

#define spin_initlock(lock)   __spin_initlock(lock, #lock)

extern struct spinlock kernel_lock;

static inline void
lock_kernel(void)
{
	spin_lock(&kernel_lock);
}

static inline void
unlock_kernel(void)
{
	spin_unlock(&kernel_lock);

	// Normally we wouldn't need to do this, but QEMU only runs
	// one CPU at a time and has a long time-slice.  Without the
	// pause, this CPU is likely to reacquire the lock before
	// another CPU has even been given a chance to acquire it.
	asm volatile("pause");
}



// Mutual exclusion spin locks.

// The big kernel lock
struct spinlock kernel_lock = {
#ifdef DEBUG_SPINLOCK 
	.name = "kernel_lock"
#endif
};
spinlock锁的初始化
void
__spin_initlock(struct spinlock *lk, char *name)
{
	lk->locked = 0;
}

// Acquire the lock.
// Loops (spins) until the lock is acquired.
// Holding a lock for a long time may cause
// other CPUs to waste time spinning to acquire it.
void
spin_lock(struct spinlock *lk)
{

	// The xchg is atomic.
	// It also serializes, so that reads after acquire are not
	// reordered before it. 
	while (xchg(&lk->locked, 1) != 0)
		asm volatile ("pause");

}

// Release the lock.
void
spin_unlock(struct spinlock *lk)
{
	// The xchg serializes, so that reads before release are 
	// not reordered after it.  The 1996 PentiumPro manual (Volume 3,
	// 7.2) says reads can be carried out speculatively and in
	// any order, which implies we need to serialize here.
	// But the 2007 Intel 64 Architecture Memory Ordering White
	// Paper says that Intel 64 and IA-32 will not move a load
	// after a store. So lock->locked = 0 would work here.
	// The xchg being asm volatile ensures gcc emits it after
	// the above assignments (and after the critical section).
	xchg(&lk->locked, 0);
}

原理还是很简单的,只是基于汇编层次的全局变量的busy waiting.










          春节, 快乐

技术分享

JOS中 "spinlock" 的实现

标签:operating system   kernel   

原文地址:http://blog.csdn.net/cinmyheart/article/details/43880517

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!