2. So you want to start a project
Bugs!
C++?
Control!
Dangling pointers Double frees
Segmentation faults Data races
…
2
3. What about GC?
No control.
Requires a runtime.
Insufficient to prevent related problems:
resource management, data races.
3
4. Rust’s Solution
Type system enforces ownership and
borrowing:
!
1. All memory has a clear owner.
2. Others can borrow from the owner.
3. Owner cannot free or mutate the
memory while it is borrowed.
4
14. fn example() {
let mut names = Vec::new();
names.push(..);
names.push(..);
let name = &names[1];
names.push(..);
print(name);
}
names
data
length
capacity
“brson”
“pcwalton”
name
“brson”
“pcwalton”
“acrichto”
Sharing: more than
one pointer to same
memory.
Dangling pointer: pointer
to freed memory.
Mutating the vector
freed old contents.
14
15. fn example() {
let mut names = Vec::new();
names.push(..);
names.push(..);
let name = &names[1];
names.push(..);
print(name);
}
Borrow “locks”
`names` until `name`
goes out of scopeError: cannot mutate
`names` while borrowed
15
16. fn example() {
let mut names = Vec::new();
names.push(..);
names.push(..);
while something-or-other {
let name = &names[1];
…
names.push(..);
print(name);
}
names.push(..);
}
Outside of borrow scope — OK.
Scope of borrow
in this case covers
only the loop body.
16
23. fn par_computation(input: &Vec<i32>,
output: &mut Vec<i32>) {
let len = output.len();
let (l, r) = output.split_at_mut(len/2);
let left_thread = scoped(|| computation(input, l));
computation(input, r);
left_thread.join();
}
Create two disjoint views
Start a “scoped” thread
to process `l`Process `r` in the
main thread
Block until `left_thread`
completes (implicit)
23
24. What about data races?
fn par_computation(input: &Vec<i32>,
output: &mut Vec<i32>) {
let len = output.len();
let (l, r) = output.split_at_mut(len/2);
let left_thread = scoped(|| computation(input, l));
computation(input, l);
left_thread.join();
}
Process `l` in
both threads?
24
25. fn par_computation(input: &Vec<i32>,
output: &mut Vec<i32>) {
let len = output.len();
let (l, r) = output.split_at_mut(len/2);
let left_thread = scoped(|| computation(input, l));
computation(input, l);
left_thread.join();
}
Shared borrow of
`input` — OK
Shared borrow of `input`
Mutable borrow of `l`
Error: `l` is mutably
borrowed, cannot access
25
26. And beyond…
Parallelism is an area of active development.
!
Either already have or have plans for:
- Atomic primitives
- Non-blocking queues
- Concurrent hashtables
- Lightweight thread pools
- Futures
- CILK-style fork-join concurrency
- etc.
All “just libraries”. And all ensure data-race freedom.
26