3 ms·
It doesn't. What Rust proves for safe Rust is that even if you were to use these incorrectly, your program is still data-race free and memory safe. That is, i
by fluffything 6y ago
It doesn't.
What Rust proves for safe Rust is that even if you were to use these incorrectly, your program is still data-race free and memory safe.
That is, if you use relaxed where you actually wanted to use sequential consistency, your program might do many sorts of incorrect things (e.g. a counter is incremented in the wrong order), but it will not have undefined behavior (it won't dereference a null pointer, doing an access out of bound, double free, or having a data-race).
To write atomic code that creates a data-race, you'd need to use unsafe Rust, and then your program would have UB.
Rust proves this for safe Rust using ownership + borrowing, and `Sync`+`Send`. Ownership and borrowing deal with "aliasing xor mutability" which essentially eliminates all data-races, because a data-race requires a conflicting access involving two aliases where one is a write, and these two features prevent that from happening. `Sync` and `Send` provide proofs that some concurrent accesses are ok, e.g., an atomic relaxed write that conflicts with an atomic relaxed read is ok (what's not ok is unsynchronized conflicting accesses).
As mentioned this does not proves that your program has no logic bugs, only that it has no data-races and UB. It is possible to write programs in safe Rust that do not do what you intend.
- mratsim 6y agoWell if you misuse atomics you have a data race and undefined behaviors.
- fluffything 6y agoAs explained above, if you do that in safe Rust, your program does not compile. So no, you don't have data races or undefined behaviors. If you mix safe Rust with unsafe Rust, and your unsafe Rust has a bug that causes a data-race, then you only have to search for the bug in the 0.00001% of your code base that uses unsafe Rust. Which is many orders of magnitude better than even "safe" languages like Java.
- mratsim 6y agoThen if I'm writing a concurrent queue or concurrent hash-table I'm on my own since 100% of my codebase is unsafe Rust. Which was exactly my point. Rust provides no support for fearless concurrency because actual concurrent code, the code that deals with synchronization, is considered unsafe. I.e. fearless concurrency is a misleading statement and should not be trusted if you write concurrent code. Also, I suppose you didn't try to write any concurrent data structure. Even a hundred of lines of concurrent code is incredibly hard to debug without tools when it involves multiple threads synchronizing with each other.
- fluffything 6y ago> Then if I'm writing a concurrent queue or concurrent hash-table I'm on my own since 100% of my codebase is unsafe Rust. Sure. And if you are writing a concurrent application with 500k LOC , 99.99999999% of your code will be safe Rust. Safe Rust that you can refactor at will - at least, in my anecdotal experience of working 3 years full-time on a concurrent >100kLOC Rust application, I have yet to see a big refactor that introduces a concurrency or memory safety bug. In my previous 15 years of doing the same in C++, I actually have to see a refactor by myself or others that did not introduce multiple bugs. > Then if I'm writing a concurrent queue or concurrent hash-table I'm on my own since 100% of my codebase is unsafe Rust. You can write a concurrent queue using safe Rust (e.g. it is trivial to write a spinlock using safe Rust that you can use for that). You are choosing not to do that, and provide your own instead. Your job is not to write the unsafe code, but to _prove_ that it is safe to use from safe Rust. Once you do that, the other 99.999999999% of your application can just use it without issues. If you don't want to do that, Rust belt has soundness proofs for most concurrency primitives in the standard library. Aaron Turon's thesis has similar proofs for the ones in crossbeam. Etc. > I suppose you didn't try to write any concurrent data structure. You suppose wrong. > Even a hundred of lines of concurrent code is incredibly hard to debug without tools when it involves multiple threads synchronizing with each other. So don't do it? I've done it a couple of times, and the first thing I do is set up the fuzzer and thread-sanitizer for the build. That catches most bugs early. I've never proven my implementations to be sound, but they were always good enough for my use cases. I've hitted bugs in my application when using them, but finding those bugs was always trivial, since they are only located in the 100 LOC of unsafe code. --- I think you are fully misunderstanding the claim fearless concurrency. It is a claim about safe Rust, and you can write huge, complex, and extremely efficient concurrent applications using safe Rust without having to write one line of unsafe Rust yourself, and using only unsafe Rust code that has been proved correct. If the only thing you use Rust for is writing concurrent data-structures, Rust is very specific that these claims do not apply there. You seem to not have understood this yet, and without having understood that, the chances that your implementations are correct are very thin. I hope you are not using them for anything important.