I like this explanatory comment by Manishearth, a Servo dev, in the thread over on /r/rust: "This blog post brought to you by the 'how many times can you say 'fearless concurrency' and keep a straight face' cabal. "Seriously though, I now appreciate that term a lot more. One thing that cropped up in the review of this post was that I didn't have examples of bugs Rust prevented. Because I couldn't think of any concret…
I've spent the last few days aggressively parallelizing some Rust code with crossbeam, and it's really just... painless (once you're used to Rust). Rust actually understands data races, and it grumbles at me until my code is provably safe, and then everything Just Works. The Rayon library is also lovely for data parallelism. Sometimes, I think, "Rust is basically a nicer C++ with the obvious foot guns removed and gre…
Fearless Concurrency in Firefox Quantum
51–60 of 177 posts
Re: Fearless Concurrency in Firefox Quantum
#52Earlier quoted context omitted.
Sure, the obvious example is your classic thead1 i++, thead2 i-- bug. In C you run each thread a large number of times in parallel and you end up with something other than 0. The solution is to use atomic operations or locks. Rust doesn't allow having two mutable references to the same memory location at the same time, so you would never encounter that.
> Rust doesn't allow having two mutable references to the same memory location at the same time, so you would never encounter that. Wouldn't that make a whole class of efficient algorithms impossible though? Like let's say you have an std::list and you want a sorted "view" of the elements. In C++ you'd create an array of pointers and then sort it, and after that you can just modify whatever each slot points to. In Ru…
Here's one way to think of it: There's the kind of code that Rust "wants" you to write, and then there's the kind of code that it allows to write.
Rust "wants":
- Lots of immutable data, with relatively sparing use of mutability.
- Clear ownership and borrowing.
Rust allows:
- Pretty much anything you could write in C, with the possible exception of bitfields in structs. You wanna directly access the pic8259 chip from kernel space? Have fun: https://github.com/emk/toyos-rs/blob/fdc5fb8cc8152a63d1b6c85...
The question is, is it worth exercising that full power for "ordinary" Rust code? To use your example, if you have a data structure D and a view V, can you reach "through" V and mutate the underlying D? Of course you can do this, if you really need to. You have lots of choices, including (for example) cells, locks, tricky lifetime annotations and/or unsafe code.
But in practice, it's usually not worth the hassle. What I do in a case like this is step back and ask myself, "How would I solve this problem in a functional language like Clojure, ML or Haskell?" Oftentimes, that will give me a nice, simple solution that Rust likes. But sometimes I actually do need to do things the hard way.
Part of being happy in Rust is learning how to minimize the use of mutable data. For example, if you're writing a video game and you need to update your "world state", do you really need to mutate the existing state? Or can you write a function that takes the old world state and the player's input, and uses them to compute a brand new world state? The latter actually eliminates all kinds of subtle bugs, and it can be done efficiently.
Re: Fearless Concurrency in Firefox Quantum
#53Earlier quoted context omitted.
Quoting what I just replied in that thread: > Given that this Servo code replaces an existing code base, couldn't we get a "guestimate" by looking at how many unsolved bug reports are now closed because their associated previous (presumably C++) code has been replaced? How many open bugs existed in Stylo's precursor that are removed now?
But was the existing code base that was replaced running concurrently?
Re: Fearless Concurrency in Firefox Quantum
#54Earlier quoted context omitted.
Note that the panic you get by calling unwrap() where you shouldn't isn't a crash. It's a controlled program exit due to an unexpected condition. While yes, the panic will cause your program to stop, it will do it in a clean deterministic way (with a backtrace). Actual crashes (due to segfaults) can happen a long way from the bug that actually caused the issue, can happen intermittently and generally be a nightmare t…
When this controlled program exit happens, does your monitoring system wake your operations staff up? If so, it's a crash.
Heck, your monitoring system could still notice the program exiting and call your operations stuff in Rust's case too.
And a user with sudo rights killing -9 a program you run might or might not send anything to your monitoring system -- but that wont be a crash either.
I think the important point the parent is trying to make is between a crash and a controlled exit, that is whether you get a stacktrace, things can be called to cleanup, etc.
Merely calling all the cases just "crash" would lose that distinction. It's like calling all vehicles "vehicles". Sure, it's accurate, but I want to know if it was a car, a motorcycle, a truck or whatever.
Re: Fearless Concurrency in Firefox Quantum
#55Earlier quoted context omitted.
Sure, the obvious example is your classic thead1 i++, thead2 i-- bug. In C you run each thread a large number of times in parallel and you end up with something other than 0. The solution is to use atomic operations or locks. Rust doesn't allow having two mutable references to the same memory location at the same time, so you would never encounter that.
> Rust doesn't allow having two mutable references to the same memory location at the same time, so you would never encounter that. Wouldn't that make a whole class of efficient algorithms impossible though? Like let's say you have an std::list and you want a sorted "view" of the elements. In C++ you'd create an array of pointers and then sort it, and after that you can just modify whatever each slot points to. In Ru…
let vec_of_refs = ll.iter_mut().collect();
vec_of_refs.sort_unstable();
The downside is you can't have this vector at the same time as you access the underlying LinkedList. Another option you can do with other container types is to have a vector of indices, but this is extremely inefficient with a LinkedList.A popular approach is to have both views be indices into an underlying vector where the actual, mutable data is stored. If that isn't good for your situation, it's probably time to use `unsafe` to build an appropriate data structure.
Re: Fearless Concurrency in Firefox Quantum
#56Earlier quoted context omitted.
Borrowing from https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.h... (linked to from the original post), the following code tries to access a lock-protected vector. fn use_lock(mutex: &Mutex >) { let vec = { // acquire the lock let mut guard = lock(mutex); // attempt to return a borrow of the data access(&mut guard) // guard is destroyed here, releasing the lock }; // attempt to access the data outside of t…
Thanks (upvoted)! However how in the world would the compiler know if the mutex belongs to the same vector you are accessing? (Unless you're saying the mutex wraps the vector implying that each vector can have one corresponding mutex at most? Which seems quite limiting?)
The mutex owns the vector. Locking it returns a MutexGuard, which is a smart pointer/reference to the data it owns[0]. You can nest mutexes and structures if you need something slightly more flexible than a single big lock.
Having multiple (side-by-side( locks for a single structure sounds like a recipe for concurrency bugs & deadlocks.
> Which seems quite limiting?
If your semantics call for a mutex it makes perfect sense. There are other types of locks if you don't want a 1:1 relationship e.g. RWLock allows multiple readers XOR a single writer.
[0] mutable, so you can replace the structure behind the guard, you just can't keep a reference to it after you release the lock due to Rust's borrow checking semantics
Re: Fearless Concurrency in Firefox Quantum
#57Firefox Quantum is blazing fast, and I finally ditched Chrome. My only problem is that it drains my battery life fast. So whenever I'm not plugged I use Edge. Other than that, FF is amazing. It is now my default browser and I even wrote a FF add-on a few days ago using their new API!
Re: Fearless Concurrency in Firefox Quantum
#58Earlier quoted context omitted.
Quoting what I just replied in that thread: > Given that this Servo code replaces an existing code base, couldn't we get a "guestimate" by looking at how many unsolved bug reports are now closed because their associated previous (presumably C++) code has been replaced? How many open bugs existed in Stylo's precursor that are removed now?
But was the existing code base that was replaced running concurrently?
Re: Fearless Concurrency in Firefox Quantum
#59Earlier quoted context omitted.
Anecdotal evidence, so take it with a grain of salt. I switched to Firefox 2 days ago, after reading a post about how Firefox has recently got faster. I have been a Chrome user for more than a couple of years now, when I switched from Firefox because it was slow in comparison. After using Firefox for 1 day, it already seemed slower than what I was used to in Chrome. This was most noticeable on ad-laden sites that dis…
Why did you switch 2 days ago instead of waiting for 57? Just a co-incidence?
Re: Fearless Concurrency in Firefox Quantum
#60Firefox Quantum is blazing fast, and I finally ditched Chrome. My only problem is that it drains my battery life fast. So whenever I'm not plugged I use Edge. Other than that, FF is amazing. It is now my default browser and I even wrote a FF add-on a few days ago using their new API!
However Firefox has been, and always will be my daily driver for all Web browsing. It's eco system is richer, noscript and the fact that it's not a Google product is a huge selling point.