and streams interfaces with dynamic memory structures. Shared memory is also subject to race condition issues and other runtime scenarios that makes it difficult for static analysis. I'm sure these are well known issues but I'm a frustrated with language designer's 2/
Conversation
notion of concurrency. It's overly simplistic. Also, last comment on this matter, I find that messaging based kernels emphasis function oriented program structures vs data oriented ones. It's makes implementation of code for shared structures obtuse here. 3/
3
In Rust, the language has a concept of types that are thread safe and can be shared, along with types that are safe to send between threads. For example, Rc<T> uses non-atomic reference counting and isn't Send. Arc<T> is a Send variant. Mutex<T> is a Sync variation of RefCell<T>.
1
1
So you can use Arc<Mutex<T>> for thread-safe shared mutable data. It also supports sharing mutable data between threads via atomics or without any synchronization at all via the standard reference safety system which enforces that mutable references do not alias anything else.
2
1
So for example you can divide up an array into non-overlapping mutable slices (pointer + length views) sent to different threads with their lifetimes constrained by the compiler to not outlive the data. It prevents data races (not higher level race conditions) in the type system.
2
1
Things like that are decent initial step but as programmer with kernel background, not picking a fight here, type systems can be abused by inexperienced programmers. Sometimes type systems aren't the most direct or sustainable way of writing that type of code
2
Linux kernel driver layers can have rather complicated nested structures. Some are a hybrid of of two subsystems like USB and ALSA (audio). Both have smaller structures inside them per each subsystems. In the case of a class compliant USB audio driver, both subsystems 1/
2
are combined into one structure. They then have to share references in the code across subsystem which, from my picture of modern type systems, can be really complicated if it's in the form of type inheritance. Maybe i'm misunderstanding you here but that's my internal picture 2/
1
Rust can represent complex data structures and doesn't lose safety in normal Rust code. Arc<Mutex<T>> is a very flexible building block for mutable data structures shared across threads. Arc and Rc support weak pointers too, and you can get references to the contents.
1
1
The way that Mutex<T> works is that you call the method to obtain the lock, and it gives you a mutable reference that the compiler prevents from outliving the lock scope. It simply uses the existing language features, just like the collections / iterators. It's pure library code.
1
1
RefCell<T> is pretty much the same thing for single-threaded cases, if you need dynamic mutable references for something that cannot be represented via the usual static aliasing checks. It's usually not needed as the rules for static checks can represent a lot of patterns.
You're usually just using data owned by local variables, moving ownership around and passing around references tied to the lifetimes of those local variables. Types like Rc<T> and RefCell<T> are a safe escape hatch for complex patterns but in idiomatic code they're pretty sparse.
1
1
And even if you're using Rc<T>, you'll mostly be using very few Rc<T> owners that you pass around by moving ownership along with lots of lightweight references into the data, which the compiler guarantees do not outlive the reference counted pointer type they were derived from.
1
Show replies

