kalloc.c char* kalloc(void)
トップページ
jupiteroak.hatenablog.com
kalloc.c
https://github.com/mit-pdos/xv6-public/blob/master/kalloc.c#L82
char* kalloc(void) { struct run *r; if(kmem.use_lock) acquire(&kmem.lock); r = kmem.freelist; if(r) kmem.freelist = r->next; if(kmem.use_lock) release(&kmem.lock); return (char*)r; }
kalloc関数は、4KBのメモリ領域を割り当てます。
戻り値 char* r
メモリ領域の割り当てに成功した場合は、そのメモリ領域の先頭アドレスが戻り値となります。
メモリ領域の割り当てに失敗した場合は、0が戻り値となります。
処理の内容
- クリティカルセクションの入口を定める
- メモリの割り当てのために連結リストの要素を1つ取り除く
- クリティカルセクションの出口を定める
- 割り当てる4KBのメモリ領域の先頭アドレスを戻り値としてリターンする
クリティカルセクションの入口を定める
if(kmem.use_lock) acquire(&kmem.lock);
kmem.use_lockが1の場合は→連結リストのヘッダーであるkmem構造体をこれから排他制御する場合は、acquire関数を呼び出してロックを取得し、クリティカルセクションの入口とします。
メモリの割り当てのために連結リストの要素を1つ取り除く
r = kmem.freelist; if(r) kmem.freelist = r->next;
連結リストの先頭要素のアドレスを取得します(連結リストのヘッダーであるkmem構造体のfreelistが参照しているアドレスを取得します)。
アドレスrが0ではない場合は→取得した連結リストの要素r(run構造体)が存在する場合は、取得した要素rの次の要素を、連結リストの新しい先頭要素にします。
そのために、連結リストのヘッダーであるkmem構造体のfreelistが、取得した要素rの次の要素を参照できるようにします(連結リストのヘッダーであるkmem構造体のfreelistに、r->nextの値を格納します)。
クリティカルセクションの出口を定める
if(kmem.use_lock) release(&kmem.lock);
kmem.use_lockが1の場合は→フリーリストのヘッダーであるkmem構造体を排他制御していた場合は、release関数を呼び出してロックを解放し、クリティカルセクションの出口とします。
割り当てる4KBのメモリ領域の先頭アドレスを戻り値としてリターンする
return (char*)r;
割り当てる4KBのメモリ領域(取り除いた連結リストの要素)の先頭アドレスを戻り値としてリターンします。