xv6, line by line
kernel/sleeplock.c

kernel/sleeplock.c

C · 55 lines · annotated 100% · kernel · upstream

About this file

The four functions of the sleep lock. They show the sleep and wakeup pattern in its simplest form: check a condition under a spinlock, and if it is not met, register on a channel, release the spinlock and sleep; re-check after every wakeup.

Why have a second kind of lock? A spinlock is the wrong tool when the wait can be long. Reading a disk block takes a long time by CPU standards, and a CPU spinning for it would be wasted, with interrupts off. Worse, a process may not sleep while holding a spinlock at all (sched panics). Holding a sleep lock does not by itself turn interrupts off, and it may be held across sleep, so the buffer cache (bread) and the inode layer (ilock) hold one during disk I/O.

The cost: only a process can use a sleep lock, since waiting means calling sleep. Interrupt handlers and the scheduler never do.

Read before: kernel/sleeplock.h, kernel/spinlock.c, and sleep_prepare, sleep and wakeup in kernel/proc.c. The concept page Locks and interrupt state puts these functions next to every other lock in the kernel.

1// Sleeping locks
3#include "types.h"
4#include "riscv.h"
5#include "defs.h"
6#include "param.h"
8#include "spinlock.h"
9#include "proc.h"
12void
15 initlock(&lk->lk, "sleep lock");
17 lk->locked = 0;
18 lk->pid = 0;
21void
25 while (lk->locked) {
30 }
31 lk->locked = 1;
32 lk->pid = myproc()->pid;
36void
40 lk->locked = 0;
41 lk->pid = 0;
46int
49 int r;
52 r = lk->locked && (lk->pid == myproc()->pid);
54 return r;