OS起動編⑫ binit() (Xv6を読む~OSコードリーディング~)

前回
jupiteroak.hatenablog.com
トップページ
jupiteroak.hatenablog.com




main.c(一部抜粋)
https://github.com/mit-pdos/xv6-public/blob/master/main.c#L31

int
main(void)
{
  ...
  binit();         // buffer cache
  ...

bio.c
https://github.com/mit-pdos/xv6-public/blob/master/bio.c#L38

void
binit(void)
{
  struct buf *b;

  initlock(&bcache.lock, "bcache");

//PAGEBREAK!
  // Create linked list of buffers
  bcache.head.prev = &bcache.head;
  bcache.head.next = &bcache.head;
  for(b = bcache.buf; b < bcache.buf+NBUF; b++){
    b->next = bcache.head.next;
    b->prev = &bcache.head;
    initsleeplock(&b->lock, "buffer");
    bcache.head.next->prev = b;
    bcache.heshad.next = b;
  }
}

binitでは、バッファキャッシュとして利用する双方向リストを作成します。バッファキャッシュは、ファイルの読み取りを効率よく行う(ハードディスクから再読み込みする回数を減らすなど)ために使用されます。


処理の内容

バッファキャッシュに関わるロックを初期化する

initlock(&bcache.lock, "bcache");

initlock関数を呼び出して、バッファキャッシュ(bcache構造体)に関わるロックを初期化しています。

バッファキャッシュとして利用する双方向リストのヘッダーのnextとprevを初期化する

bcache.head.prev = &bcache.head;
bcache.head.next = &bcache.head;

bcache.headは、バッファキャッシュとして利用する双方向リストのヘッダーとなります。ヘッダー(bcache.head)のnextとprevの初期値には、自身を指すアドレス値(&bcache.head)を設定します。

バッファキャッシュとして利用する双方向リストを作成する

  for(b = bcache.buf; b < bcache.buf+NBUF; b++){
    b->next = bcache.head.next;
    b->prev = &bcache.head;
    initsleeplock(&b->lock, "buffer");
    bcache.head.next->prev = b;
    bcache.heshad.next = b;
  }

バッファキャッシュとして利用する双方向リストを作成します。
具体的には、bcache構造体内にあるhead(buf構造体の変数)をヘッダーにしてbuf[NBUF](buf構造体の配列)が連なる双方向リストを作成します。
説明の都合上、initsleeplockの説明を後回しにします。

新しく追加する要素(b)のnext が ヘッダーの次の要素 を指すようにする

b->next = bcache.head.next;

新しく追加する要素(b)のprev が ヘッダー を指すようにする

b->prev = &bcache.head;

ヘッダーの次の要素のprev が 新しく追加する要素(b) を指すように変更する

bcache.head.next->prev = b;

ヘッダーのnext が 新しく追加する要素(b) を指すように変更する

bcache.head.next = b;


上記の手順をb < bcache.buf+NBUF(30)の継続条件式が成立する限り繰り返します(30回繰り返します)。

バッファに関わるスリープロックを初期化する

initsleeplock(&b->lock, "buffer");

双方向リストのバッファに関わるスリープロックを初期化します。




次回
jupiteroak.hatenablog.com