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が戻り値となります。


処理の内容

クリティカルセクションの入口を定める

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のメモリ領域(取り除いた連結リストの要素)の先頭アドレスを戻り値としてリターンします。