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では、バッファキャッシュとして利用する双方向リストを作成します。バッファキャッシュは、ファイルの読み取りを効率よく行う(ハードディスクから再読み込みする回数を減らすなど)ために使用されます。
処理の内容
- バッファキャッシュに関わるロックを初期化する
- バッファキャッシュとして利用する双方向リストのヘッダーのnextとprevを初期化する
- バッファキャッシュとして利用する双方向リストを作成する
- バッファに関わるスリープロックを初期化する
バッファキャッシュに関わるロックを初期化する
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回繰り返します)。