sleeplock.c void acquiresleep(struct sleeplock *lk)

トップページ
jupiteroak.hatenablog.com


sleeplock.c
https://github.com/mit-pdos/xv6-public/blob/master/sleeplock.c#L22

void acquiresleep(struct sleeplock *lk)
{
  acquire(&lk->lk);
  while (lk->locked) {
    sleep(lk, &lk->lk);
  }
  lk->locked = 1;
  lk->pid = myproc()->pid;
  release(&lk->lk);
}

acquiresleep関数は、排他制御の対象となる共有資源に関連しているスリープロックを取得します(スリープロックが取得できなかった場合は、プロセスを休止させます)。

引数 sleeplock *lk
取得対象となるスリープロックのアドレスです。


処理の内容

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

acquire(&lk->lk);

sleeplock構造体を排他制御するために、acquire関数を呼び出してsleeplock構造体に関連しているロックを取得し、クリティカルセクションの入口とします。

別のプロセスがスリープロックを保持している場合は現在実行中のプロセスを休止させる

while (lk->locked) {
    sleep(lk, &lk->lk);
  }

lk->lockedが真となる場合→lk->lockedの値が1となる場合→別のプロセスがスリープロックを保持している間は、sleep関数を呼び出してプログラムの制御を別のプロセスに移します(CPU資源を別のプロセスに譲ります)。

スリープロックを取得する

lk->locked = 1;

whileループから脱出した場合→別のプロセスがスリープロックを解放している場合は、lockedメンバに1を設定し、現在実行中のプロセスにスリープロックを取得させます。

スリープロックを取得しているプロセスを記録する

lk->pid = myproc()->pid;

現在実行中のプロセスのプロセスIDを使って、スリープロックを取得しているプロセスを記録します。

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

release(&lk->lk);

release関数を呼び出してsleeplock構造体に関連しているロックを解放し、クリティカルセクションの出口とします。