Course Overview
An intensive, project-driven exploration of operating systems and system programming. The coursework focused on kernel-level development, concurrency control, memory management, and file systems. A significant portion of the assignments was implemented in Rust to enforce memory safety and data-race freedom in complex concurrent environments.
Core Project: Pintos OS Kernel Development
Co-developed a monolithic instructional operating system (Pintos) in C, implementing critical subsystems from the ground up.
1. User Programs
Engineered a secure, POSIX-compliant system call interface and process execution environment, implementing rigorous user-kernel boundary validation and memory protections to guarantee kernel integrity.
- Syscall Dispatch & Execution: Implemented the core
syscall_handler()infrastructure, supporting file operations (create,remove,open,close,filesize,tell). - User-Kernel Boundary Security: Engineered rigorous invalid input checking mechanisms (e.g., pointer validation, buffer boundary checks) to protect the kernel from malicious or buggy user-space memory access—preventing page faults from escalating into kernel panics.
- Memory Protection: Enforced Read-Only eXecutable (ROX) protections, ensuring that executable files actively running in memory cannot be modified, thereby preventing self-modifying code vulnerabilities.
2. Threads
Architected a robust 1:1 multithreading model, mapping user-space POSIX threads directly to schedulable kernel threads, enabling true parallelism and precise lifecycle management. Introducing granular synchronization primitives and comprehensive thread lifecycle management to support safe, concurrent task execution.
- Multi-Threaded Process Control: Extended the
exitandwaitprocess control syscalls to correctly handle multi-threaded processes. Only the calling thread blocks onwait; other threads in the process continue running. Onexit, all sibling threads are immediately prevented from executing any further user-space code, then joined and resources fully reaped before process termination. - Thread Lifecycle Syscalls: Implemented
pthread_joinandpthread_exitsyscalls, mapping user-space POSIX thread lifecycle operations directly onto kernel thread primitives. - Kernel-Backed Synchronization Primitives: Implemented the full suite of synchronization syscalls (Mutexes and Semaphores) for user programs.
3. File System
Designed and implemented a 64-entry, highly concurrent buffer cache system to minimize disk I/O bottlenecks and optimize filesystem throughput.
- Fine-Grained Synchronization: Engineered a two-tier locking architecture using a global
cache_lock(protecting metadata and reference counts) and per-sectorblock_locks (protecting dirty bits and data payloads). This decoupled design maximized parallelism for concurrent read/write operations across different cache blocks. - N-th Chance Clock Eviction: Implemented an optimized N-th chance clock replacement algorithm. Introduced dynamic eviction prioritization by granting filesystem metadata higher survivability (
chance = 2) over standard data blocks (chance = 1), drastically reducing costly disk seeks for heavily accessed inode data. - Thread-Safe Eviction & Loading: Devised a robust reference-counting (
ref_cnt) mechanism to prevent the eviction of blocks actively in use. Guaranteed atomic state transitions during page faults (evict_and_load) by strictly enforcing lock acquisition ordering—acquiring theblock_lockbefore releasing the globalcache_lock—to eliminate TOCTOU (Time-of-Check to Time-of-Use) race conditions and implicitly safely block threads waiting for disk I/O.
Additional Group Implementations
The following features were completed by the team; listed for completeness.
- Argument passing, user stack initialization and alignment
- Process control syscalls for single thread process (
exec,wait,exit) - Efficient alarm clock (sleep queue replacing busy-wait)
- Strict priority scheduling with recursive priority donation
- Extensible files (multi-level inode indexing)
- Subdirectories with absolute/relative path traversal
Individual Systems Assignments
Completed a rigorous series of individual systems programming assignments. Leveraged Rust for concurrent and distributed network systems to enforce memory safety, while utilizing C for bare-metal process and memory manipulation.
1. Distributed MapReduce Framework (hw-map-reduce-rs, Rust)
Architected a fault-tolerant, distributed MapReduce computing framework leveraging asynchronous RPCs in Rust.
- Coordinator-Worker Architecture: Engineered the core distributed topology, establishing reliable network communication channels via Remote Procedure Calls (RPC) to orchestrate data distribution and task synchronization.
- Fault Tolerance & State Management: Implemented dynamic heartbeat mechanisms to detect worker node failures and automatically reschedule stalled map/reduce tasks. Safely managed concurrent job states using Rust’s
ArcandMutexto eliminate data races.
2. High-Performance HTTP Server (hw-http-rs, Rust)
Engineered a concurrent, multithreaded web server handling raw TCP socket connections and HTTP protocol parsing.
- Thread Pool Concurrency: Designed and implemented a custom Thread Pool to multiplex incoming network requests across a bounded number of worker threads, effectively mitigating resource exhaustion and unbounded thread creation under high concurrency.
- Protocol & Request Handling: Developed robust HTTP/1.0 request parsing and static file serving mechanisms, ensuring thread-safe file descriptor management and graceful connection teardowns.
3. POSIX-Compatible Shell (hw-shell, C)
Developed a fully functional UNIX command-line interpreter, mastering complex process lifecycles, advanced job control, and Inter-Process Communication (IPC).
- Advanced Job Control: Implemented comprehensive job management, including background process execution (
&) and built-in state-control commands (fg,bg,jobs). Managed complex process state transitions (Running, Stopped, Terminated) usingwaitpidwithWUNTRACEDandWNOHANGflags. - Terminal & Process Groups: Engineered secure terminal control transfers between the shell and foreground jobs using
tcsetpgrpandtcgetpgrp. Effectively isolated background processes from the controlling terminal, implementing robust handlers forSIGTTOUandSIGTTINsignals to prevent I/O race conditions. - IPC & Data Pipelines: Designed data pipelines utilizing anonymous pipes (
pipe,dup2) and standard I/O redirection, seamlessly integrating with the job control mechanisms to manage multi-process command chains.
4. Dynamic Memory Allocator (hw-memory, C)
Built a custom user-level memory allocator (malloc, free, realloc, calloc), managing heap fragmentation and strict memory alignment.
- Free-List Management: Implemented a First-Fit/Best-Fit memory allocation algorithm utilizing an explicit free-list data structure to manage unallocated heap chunks dynamically requested via
sbrk. - Pointer Arithmetic & Coalescing: Extensively utilized raw pointer arithmetic to manipulate memory block metadata headers. Engineered block splitting and coalescing algorithms to merge adjacent free blocks, severely reducing internal and external memory fragmentation.
Technical Stack
- Languages: C (Kernel), Rust (User-space/Systems tools), x86 Assembly
- Concepts: Context Switching, POSIX Threads, Syscall ABI, Concurrency Control, Cache Hierarchy.
- Tools: GDB, Docker, QEMU, Git.