日期:2014-05-16  浏览次数:20578 次

(莱昂氏unix源代码分析导读-36) 缓存管理(下)

                                      by cszhao1980

理解了上述内容,下面的这些程序就不难理解了。

首先是函数brelse(buf bp),该函数将传入的缓存归还到AV队列中,函数采用尾插法,

即缓存会插到AV队列的队尾——这样做显然有助于提高“延迟写”技术的效率。莱昂

特别指出,brelse没有清理B_DONE标志,这一点非常重要,读完本章后大家就会明白。

 

接下来是binit()函数,完成初始化:

(1)         每个缓存都被放入到空闲设备队列(bfreelist b队列)中;(有趣的是,使用头插法)

(2)         每个缓存都通过调用brelse放入到AV队列中;

(3)         初始化每个设备的b list——都为空(仅有头结点)。

 

还有notavail()函数,其作用是将传入的缓存从AV队列中取下来,并为缓存设置B_BUSY

志,表示该缓存已经被某设备占用,not available了。

 

clrbuf()函数就比较简单了,它将缓存区清0

 

incore()有两个参数:设备号(adev)和块号(blkno),它会Loop该设备的任务队列(b队列),

看是否已经为此块分配了缓存(b_blkno == blkno)。

 

getblk(dev, block)相对比较复杂,它的作用是为指定设备的指定块分配一个缓存。

(1)     它首先检查该设备的b队列,看是否已经为此block分配过缓存,如果有,则检查B_BUSY标记;

                   i.     如置位,则设置B_WANTED标记后睡眠;醒来后,跳回程序开头;

                  ii.     否则,调用notavail占用此缓存(注意,如果B_BUSY未置位,则此缓存已经被归还到AV队列了);

(2)     如果没有这样的缓存,则需要直接从(bfreelist的)AV队列中分配。

                如果该队列为空,则B_WANTED置位后睡眠;

(3)