1. Simple_lock
我发现如果单纯定义一个Simple_lock型的变量的话,不需要经过lock_alloc,只要用simple_lock_init初始化一下后也是可以用的,比如:
点击(此处)折叠或打开
-
Simple_lock s_lock;
-
-
simple_lock_init(&s_lock);
-
// enter the critical section
-
simple_lock(&s_lock);
-
...
- simple_unlock(&s_lock);
点击(此处)折叠或打开
-
void lock_alloc ( lock_addr, flags, class,
-
void *lock_addr;
-
int flags;
-
short class;
- short occurrence;
知道了lock instrumentation之后,我终于明白lock_alloc里的第三个参数class的意义了,但是occurrence还是很困扰我。
2. Complex_lock
字面意义上的复杂锁,上篇博文中没提这个,是因为当时我觉得Simple_lock已足够满足我们的要求。最近又使劲看文档,IBM按照锁的粒度把Simple_lock归结到MP-Safe里面,也就是说使用Simple_lock能确保MP安全,但不够efficient,如果要efficient,您得使用Complex_lock,即所谓的MP-efficient 。在lock_instrumentation这方面,两者的使用完全一样。为啥Complex lock就efficient呢,主要是因为后者是shared read,也就是说对于Complex_read, 如果一个代码执行路径通过lock_read进入critical section后,另一条执行路径如果也使用lock_read,它也可以进入这个section中。我用lock_mine在代码中测试了一下,发现lock_read之后,lock_mine显示当前路径没有获得锁,所以下面的代码序列执行起来是没有问题的:
lock_read(&lock);
lock_read(&lock);
也就是read-read可以共享critical section,但是read-write是exclusive的。这在Linux内核中其实是rwlock嘛,:-)
但是Complex_lock不能用在process-interrupt这种环境下,我猜是Complex如果发现它要获取的锁当前被别人占用,它就会睡眠。Simple_lock就不存在这方面的限制,但是它不对读写操作进行区分,因而被无情地划分到了MP-safe这一档次里,下面的代码会直接造成死锁:
simple_lock(&s_lock);
simple_lock(&s_lock);
AIX内核中还有lockl和kernel_lock,不过文档明确说这两种锁在新代码中不应该使用,所以就不提了。