|
extern inline void spin_lock(spinlock_t *plock) { __asm__ __volatile__( spin_lock_string :"=m" (__dummy_lock(plock))); } |
|
其实,这段程式码是经过我削减后的,至于削减掉的程式码是用来做
debug 的,所以,就不列出来,有兴趣的朋友不彷自行去看看。在上图中,spin_lock_string 是个 macro,加上 □asm□
语法,我将他展开成下面这个样子:
|
extern inline void spin_lock(spinlock_t *plock) { 1: lock ; btsl ,plock; jc 2f; .section .text.lock,"ax" 2: testb ,plock; rep;nop; jne 2b; jmp 1b; .previous } |
|
让我们来看看 spin_lock() 这段组合语言是什幺意思。在
Linux 底下,组合语言是用 AT&T 的语法,跟平常我们在 PC 底下使用的 Microsoft 语法不相同,主要的差别是 source 和
destination 的位置相反。基本上,spinlock 有两种状态,第一种被锁住的状态(lock),第二种则是没被锁住的状态(unlock);当
spinlock 被锁住时,spinlock_t.lock 会被设为 1,当没被锁时,则会设回 0,各位能够去看我们之前所列出来的使用方法,他会将
spinlock_t 结构的初始值设为 SPIN_LOCK_UNLOCK,现在再来看看这个 constant 的值,能够发现他其实就是将
spinlock_t.lock 设为 0 而已。
|
#define SPIN_LOCK_UNLOCKED (spinlock_t) |
|
所以,检查其状态就变成了 spin_lock()
的首要工作,假如已被锁住,则 CPU 就不能去使用他所保护的资料结构,而假如没上锁,则能够从 spin_lock()
传回,接下去使用他所保护的资料。所以,检查其状态我们能够检查 spinlock_t.lock 的第 0 个 bit。btsl , plock 会将
plock 的第 0 个 bit 值传到 flag 旗标的 carry 并把 plock 的第 0 个 bit 设为 1,其中 是在 AT&T
语法中是指数字,也就是 immediate value。所以,再来只要检查 carry 的值就能够了。当 carry 的值是 1 时,表示 spinlock
是上锁状态的,就跳到 label 2 的地方去执行,在程式码里,我们能够看到 jump 指令后面接着 2b,2f 及 1b 这些字眼,这些都是指 1: 或 2:
这些 label,假如某个 label 定在 jump 的前面,则指定label 时,要加上 b(backward),假如在后面,则加上
f(forward)。在 label 2 这段程式码里,他不停的做回圈,执行 nop 指令,每次的回圈都会去检查一次 spinlock_t.lock 的值,当
spinlock 不是锁住的状态时,就会跳离回圈,离开 spin_lock() 函式。
看完了 spin_lock(),再来看 spin_unlock() 就会发觉简单多了。
|
#define spin_unlock(lock) __asm__ __volatile__( spin_unlock_string :"=m" (__dummy_lock(lock))) |
|
其中,spin_unlock_string 相同是个
macro,展开后变成下面这个样子:
|
spin_unlock(plock) { lock; btrl , plock; } |
|
btrl , plock 这一行会将 plock 的第 0 个
bit 设为 0,能够很清楚的看出来,spin_unlock() 只是将 plock 的第 0 个 bit 再设回 0 而已。在 spin_lock() 和
spin_unlock() 里我们都能够看到 lock 这个指令在 btrl 或 btsl 的前头,这个指令的用途是当 btrl 或 btsl 在修改
plock 的值时,其他别的行程都不能来修改 plock 的值,假如有别的行程企图修改 plock 的值就会造成 exception 的发生。
看到这里,各位应该能够了解 spinlock 的运作方式及其基本的使用方法了,接下来,我要跟各位介绍 spinlock 的另一种小小的变型,叫
read-write spinlock。
第二种的使用方式
有些资料结构是这样子的,我们希望有人在修改他的内容时,别人都不能读取或修改他,但是当没有人在修改他时,能够同时有很多人去读取他的内容。我们称这样的
spinlock 为 read-write spinlock。 Kernel 为他定义了 rwlock_t,放在 里。使用方式是这样子的。
|
rwlock_t xxx_lock = RW_LOCK_UNLOCKED;
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
| | 版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2007 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86263408 86263960 86264018 86267838 86262244 86263408 售前咨询:总机转201 202 203 204 205 206 207 208 售后服务:总机转211
212 213 214 217 218 晚上0点以后拔分机225 |
| 财务咨询:总机转224
223 传真:028-86264041 财务QQ: 635483282
售前咨询QQ: 327314358 241975952 275026793 408235859 2182518 499513144 售后服务QQ: 634349278 809071471 307742704 512359778 287976517 363783715 在线咨询
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号
|
|