rust-systems-programming
Complete guide for Rust systems programming including ownership, borrowing, concurrency, async programming, unsafe code, and performance optimization
By manutej · 437 installs
npx skills add manutej/luxor-claude-marketplace --skill rust-systems-programming
Source repository · Upstream listing
Rust Systems Programming
A comprehensive skill for building high performance, memory safe systems software using Rust. This skill covers ownership, borrowing, concurrency, async programming, unsafe code, FFI, and performance optimization for systems level development.
When to Use This Skill
Use this skill when:
Building systems software requiring memory safety without garbage collection
Developing high performance applications with zero cost abstractions
Writing concurrent or parallel programs with data race prevention
Creating async/await applications for I/O bound workloads (web servers, databases)
Working with low level code, FFI, or hardware interfaces
Replacing C/C++ code with safer alternatives
Building command line tools, network services, or embedded systems
Optimizing performance critical sections of applications
Creating libraries that guarantee memory safety at compile time
Developing WebAssembly modules for near native performance
Core Concepts
The Ownership Model
Rust's ownership system is the foundation of its memory safety guarantees:
Ownership Rules:
1. Each value in Rust has exactly one owner
2. When the owner goes out of scope, the value is dropped
3. Ownership can be transferred (moved) to new owners
Move Semantics:
When a type doesn't implement Copy , assignment moves ownership rather than copying. This prevents double free errors and use after move bugs at compile time.
For Copy Types:
Borrowing and References
Borrowing allows temporary access to data without taking ownership:
Immutable Borrowing:
Mutable Borrowing:
Rust enforces exclusive mutable access to prevent data races:
Borrowing Rules:
You can have either one mutable reference OR any number of immutable references
References must always be valid (no dangling pointers)
Mutable and immutable borrows cannot coexist
Common Borrowing Error:
Lifetimes
Lifetimes ensure references are always valid:
The 'a lifetime parameter tells the compiler that the returned reference will be valid as long as both input references are valid.
Ownership Patterns for Sharing
Rc (Reference Counted) for Single threaded Shared Ownership:
Rc<T provides shared ownership with reference counting. RefCell<T enables interior mutability, enforcing borrow rules at runtime rather than compile time.
Arc (Atomic Reference Counted) for Thread safe Sharing:
Arc<T is the thread safe version of Rc<T , using atomic operations for reference counting.
Box for Heap Allocation
Box<T is an owning pointer that allocates T on the heap. Useful for:
Recursive types with known size
Large values that should not be copied on the stack
Trait objects with dynamic dispatch
Concurrency Patterns
Threads and Message Passing
Rust prevents data races at compile time through its ownership system:
Shared State with Mutex
Key Concurrency Types:
Mutex<T : Mutual exclusion lock for shared mutable state
RwLock<T : Reader writer lock allowing multiple readers or one writer
Arc<T : Atomic reference counting for thread safe sharing
mpsc : Multi producer, single consumer channels
Data Race Prevention
ThreadSanitizer Example:
This code has a data race. ThreadSanitizer (enabled with RUSTFLAGS= Zsanitizer=thread ) detects concurrent access to static mutable data:
Async Programming
Async/Await Basics
Async programming in Rust allows concurrent I/O without blocking threads:
Recursive async functions require Box::pin() to give the future a known size.
Async Closures
Async Closure with Move Semantics:
When constrained to AsyncFnOnce , the closure captures by move to ensure proper ownership.
Async Closure Borrowing:
Mutable Borrowing in Async Closures:
Common Async Errors
E0373: Async block capturing short lived variable:
Solution: Move the variable into the async block:
Unsafe Code and FFI
When to Use Unsafe
Rust's unsafe keyword allows operations that the compiler cannot verify:
1. Dereferencing raw pointers
2. Calling unsafe functions or methods
3. Accessing or modifying mutable static variables
4. Implementing unsafe traits
5. Accessing fields of unions
Unsafe Dereference Example:
Memory Safety with Unsafe
Unsafe Sync Implementation:
This is unsafe because you must manually ensure thread safety. Cell is not Sync by default, so this implementation requires careful reasoning.
FFI (Foreign Function Interface)
Calling C Functions from Rust:
Control Flow Integrity (CFI):
With CFI enabled, the type mismatched transmute causes program termination, preventing control flow hijacking.
Inline Assembly for System Calls:
This demonstrates direct system calls using inline assembly for Windows memory deallocation.
Error Handling
Result and Option Types
Rust uses Result<T, E and Option<T for error handling:
The ? Operator
The ? operator propagates errors up the call stack, similar to exceptions but explicit in the type signature.
Custom Error Types
Memory Safety and Sanitizers
AddressSanitizer
Detecting Stack Buffer Overflow:
Build with AddressSanitizer:
Output:
Detecting Heap Buffer Overflow:
Detecting Use After Scope:
AddressSanitizer output:
Performance Optimization
Zero Cost Abstractions
Rust provides high level abstractions without runtime overhead:
The compiler optimizes this to a tight loop equivalent to manual iteration.
Inlining and Monomorphization
Generic functions are monomorphized (specialized) for each concrete type:
Smart Pointer Overhead
Different smart pointers have different costs:
Box<T : Single heap allocation, no overhead
Rc<T : Reference counting, small overhead per clone/drop
Arc<T : Atomic reference counting, higher overhead for thread safety
Mutex<T : Lock acquisition overhead
RefCell<T : Runtime borrow checking overhead
Avoiding Allocations
Common Patterns and Idioms
Builder Pattern
Newtype Pattern
RAII (Resource Acquisition Is Initialization)
Closure Patterns and Errors
E0500: Closure Borrowing Conflict
Problem:
Solution:
E0502: Mutable and Immutable Borrows
Problem:
Solution:
E0505: Move of Borrowed Value
Problem:
E0524: Concurrent Mutable Borrows in Closures
Problem:
Solution 1: Sequential Execution (Non Lexical Lifetimes)
Solution 2: Rc + RefCell for Shared Mutable Access
E0507: Moving Borrowed Content
Problem:
Solution 1: Take a Reference
Solution 2: Reclaim Ownership
Production Patterns
Structured Logging
Configuration Management
Graceful Shutdown
Connection Pooling
Best Practices
API Design
1. Use References by Default : Accept &T instead of T unless you need ownership
2. Return Owned Types : Return String instead of &str for simpler APIs
3. Implement Standard Traits : Debug , Clone , PartialEq , Send , Sync
4. Use Into<T for Flexibility : fn set name(&mut self, name: impl Into<String )
5. Leverage the Type System : Use newtypes, enums, and Result for correctness
Testing Patterns
Documentation
/// let result = add(2, 2);
/// assert eq!(result, 4);
///
Dependency Management
Troubleshooting
Common Borrow Checker Issues
Issue : "Cannot borrow as mutable because it is also borrowed as immutable"
Solution : Ensure mutable and immutable borrows don't overlap in scope
Issue : "Cannot move out of borrowed content"
Solution : Clone the value, take a reference, or use Rc<RefCell<T
Issue : "Lifetime issues with references"
Solution : Add explicit lifetime annotations or restructure code to avoid complex lifetimes
Performance Issues
Issue : Slow compilation times
Solution : Use incremental compilation, reduce generic instantiations, use cargo check
Issue : Runtime performance slower than expected
Solution : Profile with perf , enable LTO, check for unnecessary allocations/clones
Issue : High memory usage
Solution : Use references instead of clones, consider streaming data, profile with Valgrind
Concurrency Issues
Issue : Deadlocks with multiple mutexes
Solution : Always acquire locks in the same order, use try lock with timeout
Issue : Data races in unsafe code
Solution : Run with ThreadSanitizer, carefully review unsafe blocks
Issue : Async tasks not making progress
Solution : Check for blocking operations in async code, use spawn blocking for CPU bound work
Quick Reference
Smart Pointer Cheat Sheet
Common Trait Implementations
Async Runtime Comparison
Resources
The Rust Book: https://doc.rust lang.org/book/
Rust by Example: https://doc.rust lang.org/rust by example/
The Rustonomicon (unsafe Rust): https://doc.rust lang.org/nomicon/
Async Book: https://rust lang.github.io/async book/
Rust Performance Book: https://nnethercote.github.io/perf book/
Crate Documentation: https://docs.rs/
Skill Version : 1.0.0
Last Updated : October 2025
Skill Category : Systems Programming, Performance, Memory Safety
Context7 Integration : Rust documentation and error code examples