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 exit and wait process control syscalls to correctly handle multi-threaded processes. Only the calling thread blocks on wait; other threads in the process continue running. On exit, 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_join and pthread_exit syscalls, 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-sector block_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 the block_lock before releasing the global cache_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 Arc and Mutex to 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) using waitpid with WUNTRACED and WNOHANG flags.
  • Terminal & Process Groups: Engineered secure terminal control transfers between the shell and foreground jobs using tcsetpgrp and tcgetpgrp. Effectively isolated background processes from the controlling terminal, implementing robust handlers for SIGTTOU and SIGTTIN signals 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.