Theme
0. Execution and Memory Basics
- Status: NOT STARTED
- Target: L1
- Priority: 8/10
- Estimated active time: 4-6 hours
- Prerequisites: none
Purpose
This module establishes the execution model needed to reason about ownership, concurrency, async runtimes, and performance without relying on misleading shortcuts.
It is an orientation layer, not a computer architecture or operating systems course. Detailed layout, allocators, page tables, scheduling, async state machines, and cache optimization are deliberately deferred to later modules.
L1 Outcome
I can explain how Rust source becomes a running process, where values and owned resources can live, and how a process, OS thread, and async task differ.
At the end of the module, stack, heap, ownership, virtual memory, threads, async tasks, and system calls should form one coherent model rather than a list of definitions.
Scope
L1 Core
- source code, compilation, linking, executable, and process;
- compile-time checks versus runtime work;
- CPU registers, caches, RAM, and storage as a conceptual hierarchy;
- byte, address, pointer, reference, and value;
- virtual address space versus physical memory;
- stack frames, thread stacks, and heap allocation;
- value location versus ownership of a resource;
- allocator purpose and allocation/deallocation;
- process versus OS thread;
- user mode, kernel mode, and system calls;
- concurrency versus parallelism;
- CPU-bound versus I/O-bound work;
- OS thread versus async task;
- relative cost model: allocation, indirection, cache miss, system call, context switch.
Awareness
- code, read-only data, static data, heap, stacks, and memory mappings inside an address space;
- paging and page faults;
- thread scheduling and context switching;
- CPU cache locality;
- dynamic linking;
- async runtime, executor, and reactor as later concepts;
- blocking and non-blocking I/O.
Deferred to L2/L3
- exact Rust type layout and ABI;
- allocator algorithms and fragmentation analysis;
- page tables, TLBs, and replacement policies;
- CPU pipelines, branch prediction, and cache-coherence protocols;
- memory ordering and atomics;
- scheduler algorithms and operating-system implementation;
Future::poll, wakers, executors, and Tokio internals;- profiling counters and performance measurement methodology.
Prerequisite Check
Answer before studying. Do not look up definitions.
- What is the difference between an executable file and a running process?
- Does a value that owns heap memory itself have to live on the heap?
- Does every thread in a process have a separate heap?
- Is a virtual address the same thing as a physical RAM address?
- What changes when a program performs a system call?
- How does an async task differ from an OS thread?
- Why does async help I/O-heavy work but not automatically make CPU-heavy work faster?
Record answers as correct, partial, or unknown. The diagnostic changes the time spent per block, but all L1 outcomes remain required.
Learning Path
Block 1 - From Source Code to Running Process
Outcomes
- distinguish compilation, linking, program loading, and execution;
- separate compile-time guarantees from runtime behavior;
- explain the difference between an executable and a process.
Concepts
- Rust source and crates;
- compiler outputs;
- machine code and executable files;
- loader and process creation;
- instructions and runtime state;
- type checking and borrow checking as compile-time work;
- allocation, I/O, scheduling, and destruction as runtime work.
Resources
| Resource | Role | Required part | Why | Stop condition |
|---|---|---|---|---|
| Guided artifact exercise below | Core | Complete the commands and explain each artifact | Direct observation is clearer than a general compiler lecture | Distinguish source, executable, and process |
| rustc-dev-guide: Overview of the compiler | Reference | Read only the opening overview when the compilation stages remain unclear | Provides the official compiler map | Place parsing, type checking, code generation, and linking in order |
Checkpoint
Close all resources and answer:
- Which work is performed before a Rust binary starts?
- Which state exists only after the executable is launched?
- Why can ownership provide runtime memory management without a garbage collector?
- Is a compiler error evidence that a process started and failed?
Exercise
Create a temporary binary outside the knowledge-base content and inspect it:
bash
cargo new execution_probe
cd execution_probe
cargo build
file target/debug/execution_probe
./target/debug/execution_probeExplain what exists after cargo build, what is created when the binary is launched, and which state disappears when the process exits.
Block 2 - Addresses and the Memory Hierarchy
Outcomes
- explain an address as a way to identify a memory location;
- distinguish virtual address space from physical memory;
- describe registers, caches, RAM, and storage without treating them as interchangeable;
- explain why locality matters without discussing optimization techniques yet.
Concepts
- bytes and addresses;
- pointers and references as address-related values with different language guarantees;
- per-process virtual address space;
- mapping virtual pages to physical memory;
- registers, caches, RAM, and persistent storage;
- latency hierarchy and locality.
Resources
| Resource | Role | Required part | Why | Stop condition |
|---|---|---|---|---|
| OSTEP, Chapter 13: The Abstraction: Address Spaces | Core | Read the chapter through the goals of virtual memory; skip historical detail on the first pass | Builds the process address-space model | Explain address-space transparency, protection, and virtualization |
| OSTEP, Chapter 2: Introduction to Operating Systems | Gap | Read the virtualization sections only if process or address-space purpose is unclear | Connects CPU and memory virtualization | Explain why the OS virtualizes machine resources |
Checkpoint
- Why can two processes use the same virtual address without referring to the same physical bytes?
- What does the operating system gain from virtual address spaces?
- Why is a memory address printed by a process normally a virtual address?
- Why can contiguous virtual memory correspond to non-contiguous physical pages?
- Why does sequential access often behave better than scattered access?
Exercise
Draw this path from memory and explain what each boundary means:
text
Rust value -> virtual address -> page mapping -> physical memory -> cache line -> CPU registerThe drawing is conceptual. Do not add page-table or cache-coherence implementation details.
Block 3 - Stack, Heap, Values, and Allocation
Outcomes
- explain stack frames and heap allocation;
- distinguish where a value is stored from what resource it owns;
- explain the conceptual representation of
String,Vec<T>, andBox<T>; - reject the idea that ownership is only about heap memory.
Concepts
- call stack and stack frames;
- one stack per thread;
- local values and temporaries;
- heap allocator;
- pointer, length, and capacity metadata;
- inline value versus indirectly owned allocation;
- allocation and deallocation;
- deterministic destruction as a preview of RAII.
Resources
| Resource | Role | Required part | Why | Stop condition |
|---|---|---|---|---|
| The Rust Programming Language: The Stack and the Heap | Core | Read from "The Stack and the Heap" through the first String representation diagram | Gives the canonical Rust-oriented model | Explain stack frame, heap allocation, pointer, length, and capacity |
| The Rust Programming Language: Memory and Allocation | Core | Read the section, but defer move semantics to Module 1 | Connects resource cleanup to Rust values | Explain why a String needs allocation management while an integer does not |
| Rust Standard Library documentation | Reference | Consult String, Vec, Box, and std::mem only for specific questions | Avoids inventing representation details | Verify a specific standard-library claim |
Checkpoint
- Does "stored on the stack" mean "has no ownership"?
- Where can the pointer, length, and capacity of a local
Stringlive, and where are its bytes? - Why does every thread need its own stack?
- Is pushing a value onto the call stack the same as heap allocation?
- What role does an allocator play?
- Can a stack value own a heap allocation?
Exercise
For each value, draw its conceptual inline state and any separately owned allocation:
rust
let n = 42_u64;
let s = String::from("rust");
let v = vec![1_u8, 2, 3];
let b = Box::new(7_u64);Do not claim exact field order or ABI. The task is ownership and indirection, not layout guarantees.
Block 4 - Processes, Threads, Kernel, and System Calls
Outcomes
- distinguish a process from a thread;
- explain what threads share and what each thread owns separately;
- explain a system call as a controlled kernel boundary;
- describe scheduling and context switching at L1 depth.
Concepts
- process and address space;
- OS thread and thread stack;
- shared process resources;
- user mode and kernel mode;
- system-call interface;
- blocking;
- scheduler and context switch;
- concurrency and parallelism.
Resources
| Resource | Role | Required part | Why | Stop condition |
|---|---|---|---|---|
| OSTEP, Chapter 4: The Abstraction: The Process | Core | Read the process abstraction and process-state sections | Establishes the running-program model | Explain process state and why the OS schedules processes or threads |
| OSTEP, Chapter 26: Concurrency: An Introduction | Core | Read through the explanation of per-thread stacks; stop before the detailed race examples | Clearly separates threads from processes | Explain shared address space and separate thread stacks |
Linux syscalls(2) | Reference | Read the description only; do not read the syscall list | Defines the kernel interface precisely | Explain why applications usually call library wrappers around syscalls |
Checkpoint
- What belongs to a process, and what belongs to an individual thread?
- Can two threads access the same heap allocation?
- Why do two threads not normally use the same call stack?
- What changes when execution enters the kernel through a system call?
- What is a context switch, and why is it not free?
- Can concurrent work run on one CPU core? Can parallel work?
Exercise
Sketch a process containing two OS threads. Include:
- one shared virtual address space;
- shared code and heap;
- one stack per thread;
- a system-call transition into the kernel;
- a scheduler choosing a runnable thread.
Block 5 - OS Threads, Async Tasks, and the Cost Compass
Outcomes
- distinguish an async task from an OS thread;
- distinguish CPU-bound from I/O-bound work;
- explain why async improves scalability for waiting-heavy workloads but does not accelerate CPU work by itself;
- use a relative cost model without inventing universal timing numbers.
Concepts
- CPU work versus waiting for external events;
- blocking thread;
- async task;
- async runtime as a user-space scheduler;
- multiple tasks on a smaller number of threads;
- concurrency versus parallelism;
- allocation, indirection, cache miss, syscall, and context-switch costs.
Resources
| Resource | Role | Required part | Why | Stop condition |
|---|---|---|---|---|
| Async Book: Why Async? | Core | Read "Async vs other concurrency models" and "Async vs threads in Rust" | Gives the official high-level comparison | Explain when threads or async are the better default |
| Q044. How does an OS thread differ from an async task? | Gap | Read only after answering the checkpoint | Provides the repository's interview answer | Correct omissions in the thread/task comparison |
| Rust Performance Book | Optional | Do not read linearly in this module | Reserved for the Performance module | Recognize where later measurement guidance lives |
Checkpoint
- Who schedules an OS thread? Who schedules an async task?
- Does an async task require a dedicated thread?
- Can several tasks execute on one thread?
- Can one task execute simultaneously on several threads at one instant?
- Why is async a strong fit for a server with many mostly waiting connections?
- Why can CPU-heavy work block progress on an async executor?
- Why should performance costs be measured rather than ranked using fixed universal numbers?
Exercise
Choose a likely execution model and justify it:
- Ten thousand mostly idle TCP connections.
- Hashing several gigabytes of independent data.
- A latency-sensitive matching loop with tightly controlled state.
- A service performing async network I/O plus occasional expensive compression.
The goal is not one universal answer. State workload assumptions and identify where threads, tasks, or a dedicated pool belong.
Blocker Misconceptions
The module cannot pass while any of these beliefs remain:
- ownership tells whether a value is on the stack or heap;
- every owned value requires a heap allocation;
- stack memory is literally stored inside the CPU;
- a reference is guaranteed to live on the stack;
- a virtual address is the physical RAM location;
- all threads have separate heaps;
- an async task is a lightweight OS thread;
- async automatically makes CPU-bound work faster;
- concurrency and parallelism mean the same thing;
- a system call is equivalent in cost and behavior to an ordinary function call;
- relative performance costs can be treated as fixed constants without measurement.
L1 Assessment
Complete the assessment without notes. Do not read the related cards until answers are recorded.
Part A - Reconstruct the Map
In five minutes, draw and explain:
text
source -> compiler/linker -> executable -> process
process
├── virtual address space
├── code and shared resources
├── heap and mappings
└── OS threads
└── one stack per thread
OS threads -> may execute async runtime -> schedules async tasksAdd the kernel boundary and show where the CPU and RAM belong. Exact cache, allocator, and memory-mapping details are not required for L1.
Part B - Conceptual Interview
Answer each question in 30-90 seconds:
- What is the difference between a program and a process?
- What happens conceptually between
cargo buildand executing the binary? - What is the difference between compile-time and runtime work in Rust?
- What is a virtual address space, and why does an OS provide one?
- What is a stack frame?
- What is heap allocation, and what does an allocator do?
- How are ownership and storage location related?
- How is a local
Stringrepresented conceptually? - What is the difference between a process and a thread?
- What is a system call?
- What is the difference between concurrency and parallelism?
- What is the difference between an OS thread and an async task?
Pass threshold: at least 9 of 12 answers must be correct, with no blocker misconception.
Part C - Recognition Drills
- Draw the inline state and owned allocation for a local
String. - Explain what two threads share and what remains per-thread.
- Classify two example workloads as CPU-bound or I/O-bound and explain the distinction.
Pass threshold: at least 2 of 3 drills must be correct and justified.
Part D - Connections
Briefly explain why this module will matter for:
- Ownership and Borrowing;
Send,Sync, and Threads;- Async and
Future; - Tokio;
- Performance and OS fundamentals.
Detailed cross-topic reasoning is not required yet. The goal is to place later modules on the map.
L2 Preview
These exercises are useful after the broad L1 pass. They do not affect the L1 result:
- Draw the inline state and owned allocations for
String,Vec<u8>, andBox<u64>and compare their indirection. - Trace a file-read request from application code across the kernel boundary and back.
- Choose between direct threads, async tasks, or a mixed model for an I/O-heavy service.
- Choose an execution model for CPU-heavy independent jobs.
- Explain why moving a
Stringdoes not require moving its heap buffer. - Identify which claims about exact performance costs require measurement.
Definition of Done
- [ ] Complete the prerequisite diagnostic before studying.
- [ ] Reconstruct the execution and memory map without notes.
- [ ] Explain every L1 Core item accurately.
- [ ] Identify every Awareness item and why it will matter later.
- [ ] Score at least 9/12 on the conceptual interview.
- [ ] Score at least 2/3 on recognition drills.
- [ ] Clear every blocker misconception.
- [ ] Explain connections to at least four later modules.
- [ ] Record weak areas and schedule the next review.
Passing the same-day assessment sets L1 PASS. Passing the cold retest sets L1 COLD PASS.
Cold Retest
Run after one to three days without warming up:
- Draw a process with two threads and several async tasks.
- Explain why ownership is independent of stack-versus-heap placement.
- Explain virtual versus physical memory.
- Compare process, thread, and async task.
- Compare CPU-bound and I/O-bound work.
- Explain a system call.
- Draw the conceptual representation of
String.
Pass threshold: at least 6 of 7, with no blocker misconception.
Assessment Record
| Date | Assessment | Result | Evidence |
|---|---|---|---|
| - | Diagnostic | NOT STARTED | - |
| - | L1 assessment | NOT STARTED | - |
| - | Cold retest | NOT STARTED | - |
Weak areas:
- None recorded.
Next review:
- Not scheduled.
Related Cards
- Q007. Is ownership related to whether a value is stored on the stack or the heap?
- Q012. What is physically moved during a Rust move?
- Q043. What is the difference between concurrency and parallelism?
- Q044. How does an OS thread differ from an async task?
- Q055. What problem does asynchronous Rust solve?
References
- The Rust Programming Language.
- Rust Standard Library.
- Operating Systems: Three Easy Pieces.
- Linux man-pages.
- Async Book.
- The Rust Performance Book.