xv6, line by line
lab 3
Lab 33 ps: a safe snapshot of the process table

Lab 3 · reveal · 15 steps · 6 commits

ps: a safe snapshot of the process table: the reference solution

You add a system call, procinfo(struct pinfo *buf, int max), that copies one record per in-use slot of the process table into a user buffer: pid, parent’s pid, state, size, name, and the hart the process is running on. On top of it you write ps.

Copying fields out of proc[] sounds like ten lines of code. It is, but the table is being changed by three harts while you read it: processes are created, scheduled, put to sleep, turned into zombies and reaped, and each field is guarded by a different rule. So the real questions are about reading shared state. Which lock, if any, protects each field you want? In which order may you take two of them? Is it safe to touch user memory while you hold one, in this kernel? What can a “snapshot” promise when the table never stands still, and what can it not? And why does the kernel’s own procdump get away with taking no lock at all?

You will answer each of these by reading the code, then check your answers against real runs on three harts: a deadlock caught with gdb (the GNU debugger) on all three harts, records torn in half by a missing lock, and a snapshot that honestly shows four processes running on a three-hart machine.

Each step shows one change on the branch ext/03-procinfo, the code around it, and the state of the machine when that code runs.

The route
  1. 1A record both sides agree on kernel/pinfo.h
  2. 2One forward declaration, one stub user/user.h
  3. 3sys_procinfo checks its arguments kernel/sysproc.c
  4. 4A private page to gather into kernel/sysproc.c
  5. 5The scan, one slot at a time, under p->lock kernel/proc.c
  6. 6name and sz, read the way procdump reads them kernel/proc.c
  7. 7What procdump does, and why it may kernel/proc.c
  8. 8Release everything, then one copyout kernel/sysproc.c
  9. 9What copyout can do while you wait for it kernel/vm.c
  10. 10wait_lock around the scan, for the parent kernel/proc.c
  11. 11The paths that fix the order kernel/proc.c
  12. 12Which hart, from c->proc kernel/proc.c
  13. 13Why state and c->proc agree under p->lock kernel/proc.c
  14. 14ps prints the snapshot user/ps.c
  15. 15The test checks only what the design promises user/procinfotest.c

Keys: ← → step · Home start