sleeping lock分析
Xv6中的sleeping lock只在文件系统中使用到,因为从磁盘读写数据可能需要数ms的时间,这时进程可以放弃cpu让其他进程运行。但是放弃cpu的同时也会锁住文件系统的一些关键数据结构,这里不能用spinlock,因为spinlock会关中断,这样容易造成死锁,所以sleeping lock能解决这一问题。
其实sleeping lock是对Xv6中的sleep和wakeup机制的进一步封装使用。总共只有4个接口,还是比较简单的。
1. initsleeplock函数
这个初始化函数很简单,主要就是初始化了spinlock和sleeping lock中的其他成员。
2. acquiresleep函数
- 当sleep lock第一次被获取的时候,不走while分支,设置好locked和pid成员后返回。
- 当sleep lock已经被别的进程获取的时候,会进入while分支执行sleep函数,sleep函数在放弃cpu之前会解锁lock,当再次运行的时候回再次获取锁。
acquiresleep主要使用的sleep接口自动解锁和上锁的特性,至于lk->locked=1这句话执行的时候是肯定不会被打断的,因为有spinlock保护,所有也就不需要使用xchg这种原子操作来更改变量值了。
3. releasesleep
releasesleep更简单了,上锁后,修改完sleep lock成员后,调用wakeup唤醒可能在等待此锁的进程,然后返回。
4. holdingsleep
holdingsleep检查一个sleep lock是否被本进程所拥有,检查原理也很简单,如下:
- 锁已经被获取
- 锁中记录的进程id和当前进程id相同
那么就表示此锁被当前进程拥有,否则不是。
评论