Master the fundamental concepts of memory management through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it works/proc/self/pagemap exposes how the kernel maps each virtual page: PFN, present, swapped, soft-dirty bits. It is the userspace microscope for paging behavior without writing a kernel module.
Each 8-byte entry per 4 KB page:
63: present0-54: PFN if presentFor example, reading pagemap for your stack VA tells you the exact physical frame backing the current stack page after a fault.
Tools like smem, pmap, and Chrome's about://memory-internals all read /proc/PID/pagemap to report real per-process memory usage instead of guessing from virtual address space size. Getting a bit offset wrong , present is bit 62, not 61 , silently reports swapped-out pages as resident, exactly the kind of bug that makes memory-usage dashboards lie to operators.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will mmap regions, touch pages selectively, and decode pagemap entries to print a map of resident pages. The task asks you to confirm demand paging by seeing present bits flip only after access.
Decode /proc/self/pagemap, Linux's window into a process's page tables. For every virtual page it holds one 64-bit entry: whether the page is present in RAM or swapped out, its physical frame number (PFN), and several flags. Tools like pmap -X and memory profilers read it together with /proc/self/maps. To make the output identical on every machine, your program gets a captured maps listing and captured pagemap entries on stdin. It computes where each entry lives in the pagemap file, decodes it, and attributes it to its mapping.
cLoading…
The entry for virtual address V is at byte offset (V / 4096) × 8 in the pagemap file.
| Bits | Meaning |
|---|---|
| 63 | page present in RAM |
| 62 | page swapped |
| 61 | file-backed page or shared anonymous page |
| 56 | page exclusively mapped (only this process maps it) |
| 55 | soft-dirty (written since the soft-dirty bits were last cleared) |
| 0-54 | PFN, if present. If swapped: bits 0-4 are the swap type and bits 5-54 the swap offset |
An unprivileged process sees PFN 0 for present pages (the kernel hides it since Linux 4.2).
For each entry:
cLoading…
[anon] when it has none, or (no mapping) for an address outside every line, followed by the permissions.present pfn 0x… phys 0x… (phys = pfn × 4096 + the address's offset within the page), or present pfn hidden when the PFN is 0. Swapped pages print swapped type T offset 0x…, and anything else not present.file (bit 61), exclusive, soft-dirty.Finally, one line per mapping (in maps order) that had at least one entry: summary PATH: P present, S swapped, N not present.
Input:
cLoading…
Output:
cLoading…
uint64_t (1ULL << 63, (e >> 5) & ((1ULL << 50) - 1), …).start ≤ V < end from the parsed maps lines.Hidden tests cover file-backed library mappings, a swapped anonymous page, several pages of one mapping, an address outside every mapping, and anonymous mappings without a path.