Lecture Note 3
Page 22 of the slide
auto data_guard = data.lock()
auto data_ptr = &data_guard
// getting ptr between acquire and release of data
// criticial section: between acquire and release
// using ptr outside the critical section can cause problem
*data_ptr = 666 // unsafe
lifetime of ptr should end at the point where the data releases!!
- Type: set of values: e.g. ${\text{True}, \text{False}}$
- value $\in$ Type: e.g. $\text{True} \in {\text{True}, \text{False}}$
- (Strong) type system: preventing undefined behavior
Rust safe api for concurrency
Intro to rust
- Shared mutable state is forbidden!
let bar1 = &mut foo.bar1;
let bar2 = &mut foo.bar1; // ERROR! two mutable borrows!
shared mutable states are source of errors
for(auto it = v.begin(); it != v.end(); ++it) {
if ((*it) == 5) {
v.push_back(-1);
// this code might reallocate the vector and invalidates it (iterator invalidation)
// or even a function call like f(it) can invalidate the iterator!
}
}
State (Data structures) and Invariant (relationship) : How to resolve shared mutable state?
- invariant guarantees conditions that systems obeys
- immutability: frozen vector (no changing in the vector)
- no sharing of the data: only single variable points to a vector
- etc.
Type-checking memory safety in c
void foo(int *p)
: what ifp
==nullptr
?void foo(int &p)
: what ifp
references object already freed?voif foo(unique_ptr<int> p)
: pitfall! we can demistify this one by type casting
References in Rust
fn foo(p: Box<i32>)
//p owns the object of type `i32`: unique reference (always safe)
fn foo(p: &i32) // immutable borrow (always safe)
// allows read, no write (mutation)
fn foo(p: &mut i32) // mutable borrow
// allows write, not sharable
- Box and mutable reference cannot exist at the same time