Linux高速缓存详解(一)

这篇博客详细探讨了Linux操作系统的高速缓存机制,包括buffer和CACHE的区别与作用,旨在帮助读者理解Linux系统中数据存储的优化策略。内容为作者的个人学习心得,可能存在一定的主观性和不准确性。
摘要由CSDN通过智能技术生成

个人学习总结,不保证正确性。。。


在Linux高速缓存概述中介绍了Linux 0.11中的高速缓存的基础结构,这一部分将详细分析Linux高速缓存部分的相关函数。

[数据结构]
这里介绍下另外和高速缓存相关的数据结构,高速缓存散列表、空闲链表指针free_list以及等待在缓存块上的指针buffer_wait。它们定义分别如下:(代码来源buffer.c)
struct  buffer_head * hash_table[NR_HASH];
static  struct  buffer_head * free_list;
static  struct  task_struct * buffer_wait = NULL;
struct  buffer_head * start_buffer = ( struct  buffer_head *) &end;
int  NR_BUFFERS = 0;

hash_table就是之前介绍过的缓存散列表,散列函数定义如下
#define  _hashfn(dev,block) ((( unsigned  )(dev^block))%NR_HASH)
#define  hash(dev,block) hash_table[_hashfn(dev,block)]
使用两个宏,_hashfn(dev,block)计算相应的设备号和逻辑块号在散列表上的索引,使用hash(dev,block),获取计算的索引值在hash_table上的项,也就是指向双向链表的指针

free_list指向所有缓存块构成的双向链表的指针,可以将其看成是整个链表的头指针

buffer_wait是一个指向进程的指针,当进程试图获取一个缓存块时。如果所有的缓存块都不是空闲的,就会让buffer_wait指向这个进程,并且让这个进程进入不可中断的睡眠状态。当有任何进程释放一个缓存块时,就会唤醒buffer_wait指向的进程。(个人对此有个问题,当所有的缓存块都非空闲时,如果有多个进程试图获取缓存块,这几个进程都会进入不可中断的睡眠状态。但buffer_wait只是指向最后调用的那个进程,因此,当缓存块被释放,只有最后那个进程被唤醒,其它进程会一直处于不可中断的睡眠状态?)

start_buffer表示缓冲区开始地址,end是由连接程序ld生成的表明程序末端的变量(来自《Linux内核完全注释》对end的解释)

NR_BUFFERS表示缓冲块的个数,NR_BUFFERS其实是一个宏,在fs.h中定义,对应变量nr_buffers。
[缓冲区的初始化]
缓冲区的初始化由buffer_init完成。缓冲区的初始化过程是这样的,从缓冲区的高地址部分开始,划分出一个个大小为1KB(BLOCK_SIZE)部分作为数据缓冲部分,也就是在Linux高速缓存概述中介绍的buffer_data部分。从缓冲区的低地址部分开始,建立对应每个buffer_data部分的缓冲块头部分,也就是buffer_head部分。初始化之后的缓冲区的示意图如下


初始化代码如下所示
/*
buffer_end表示缓冲区的结束地址
*/
void  buffer_init( long  buffer_end)
{
                  struct  buffer_head * h = start_buffer;
                  void  * b;
                  int  i;
                  /*
                 由于内存地址的640K~1M部分被用于显存和BIOS使用,所以这里需要对缓存的结束地址做调整
                */
                  if  (buffer_end == 1<<20)   //2^20=1M
                                b = (  void  *) (640*1024);  //640K
                  else
                                b = (  void  *) buffer_end;
      /*
          为了保证有足够的空间来存储缓冲块的头部和缓冲块的数据缓冲部分,需要满足b-BLOCK_SIZE>=h+1
     */
                  while  ( (b -= BLOCK_SIZE) >= (( void  *) (h+1)) ) {
                         //设置缓冲块头部的初始值,并让data指向数据缓冲部分
                                h->b_dev = 0;   
                                h->b_dirt = 0;   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值