Process Lifecycle Breakdown (Detailed Step-by-Step in English)
Example Scenario
- The shell (
sh) process is running. shcreates a child process viafork().- The child transforms into a new program,
app, viaexec(). appis a small program, occupying 1 page for code/data and 1 page for its stack.- During execution,
appcallsmalloc(), causing its heap to grow by 2 physical pages. appfinishes its task and callsexit().
In total, the app process uses 8 physical pages during its lifetime.
Let’s see how these pages are allocated and later deallocated.
Stage 1: The Birth of a Process (fork & exec)
When you type ./app and press Enter, the sh process creates a child, which then transforms into app.
Initial State
A minimal app process is born, requiring 6 physical pages in total.
1. fork() calls allocproc() – Allocating Basic Kernel Structures (4 pages)
| Page | Description |
|---|---|
| 1 | Trapframe: allocproc calls kalloc() to allocate a physical page for the process’s trapframe. It saves register states when switching between kernel and user mode. |
| 2 | L2 Page Table: allocproc calls proc_pagetable() → uvmcreate() → kalloc(), allocating a physical page for the root page table (L2). |
| 3 | L1 Page Table: proc_pagetable() maps the high-memory TRAMPOLINE. mappages() → walk() finds no L1 table, so it calls kalloc() to create one. |
| 4 | L0 Page Table: walk() finds no L0 table in the new L1 table and again calls kalloc() to allocate a physical page for an L0 table. |
2. exec() Loads the app Program – Allocating User Space (2 pages)
- The child process (copy of
sh) callsexec("app", ...). execdiscards the user memory and page tables copied fromshand creates a new user space.
| Page | Description |
|---|---|
| 5 | Code/Data Page: exec reads the executable, calls uvmalloc() → kalloc() to allocate one physical page, and loads the program’s code/data. |
| 6 | User Stack: exec again calls uvmalloc() → kalloc() to allocate one page for the initial user stack. |
Summary of Stage 1
When app starts running, the kernel has allocated 6 physical pages:
- 1 Trapframe
- 3 Page Table Pages (L2, L1, L0)
- 1 Code Page
- 1 Stack Page
Stage 2: The Growth of a Process (malloc)
app executes and requests additional memory using malloc().
Growth State
app requests 8192 bytes (2 pages) of memory, increasing total allocation to 8 physical pages.
1. malloc() calls sbrk()
malloc(8192)detects insufficient memory in its pool.- It calls the
sbrk(8192)system call to request more heap memory from the kernel.
2. sbrk() calls growproc() → uvmalloc()
growproccalculates that 2 new physical pages are needed.- It calls
uvmalloc(2 * PGSIZE).
| Page | Description |
|---|---|
| 7 | Heap Page #1: Inside uvmalloc, kalloc() allocates one physical page. |
| 8 | Heap Page #2: kalloc() allocates another physical page. |
uvmalloc then calls mappages() to establish new mappings, linking these pages to the top of the process’s heap.
Summary of Stage 2
app now occupies 8 physical pages in total:
- 6 initial pages
- 2 heap pages allocated via
malloc()
Stage 3: The Demise of a Process (exit)
When app finishes, it calls exit().
The kernel now reclaims all its resources.
Deallocation Order
1. freeproc() – Freeing Non-Page-Table Memory (1 page)
exit()executesfreeproc(p).freeprocfirst releases non-page-table resources.
| Page | Description |
|---|---|
| 1 | Trapframe: freeproc calls kfree(p->trapframe) to reclaim this page. |
2. proc_freepagetable() – Freeing All User and Page Table Pages (7 pages)
freeproc then calls proc_freepagetable(p->pagetable, p->sz), which performs two major steps:
Step A: uvmunmap() – Reclaiming All User Data Pages (4 pages)
proc_freepagetablecallsuvmunmapto unmap all user-space mappings.uvmunmapiterates over virtual addresses from 0 top->sz.
| Page | Description |
|---|---|
| 2 | Code/Data: uvmunmap finds the mapping and calls kfree(). |
| 3 | User Stack: Found and freed via kfree(). |
| 4–5 | Heap Pages: Both heap pages are unmapped and freed. |
After this step, all user-space data pages (code, stack, heap) have been reclaimed.
Step B: uvmfree() – Reclaiming the Page Table Pages (3 pages)
After uvmunmap returns, proc_freepagetable calls uvmfree to free the page table hierarchy.
| Page | Description |
|---|---|
| 6 | L0 Page Table: uvmfree recurses to the lowest level and calls kfree(). |
| 7 | L1 Page Table: Returns from recursion and frees the L1 table. |
| 8 | L2 Page Table: After returning, proc_freepagetable frees the root table (L2). |
If the user space were larger, multiple L0 or L1 tables would be freed here as well.
Final Summary
Deallocation order:
- Trapframe page
- All user data pages (code, stack, heap, etc.)
- Page table pages (bottom-up: L0 → L1 → L2)
At this point, all 8 physical pages used by the app process have been fully released back to the system —
ready to serve the next process.