> We've had the system people who used Modula-2 or Ada, and I have to say Rust looks a lot better than either of those two disasters.
From: https://www.infoworld.com/article/3109150/linux-at-25-linus-...
Linus has learned that anything he says is potentially going to quoted and quoted over and over again. So it seems like he only talks in extremes now. I always tend to look at it like he likes rust more than the other two and nothing more.
If he said the other 2 are alright, people would run with that quote, and vice versa.
This is nothing away from BetterC and other languages. If anything, this could open up ways to using languages other than C in kernel development.
That said, I don't think there's room for more than maybe two languages for the critical kernel components even in the long run. Not because of technical limitations, but human ones.
AFAIK neither Ada nor BetterC prevent memory safety bugs like Rust does... for example it appears neither of them prevent use-after-free of dynamic heap allocations, a pretty common sort of exploitable memory safety bug.
Borrow checking is done statically.
In other words, Box<> is just the equivalent of std::unique_ptr in C++.
The point here is that you can implement many kinds of complex and useful heap-allocated data structures in safe Rust code, without any reference counting, and the compiler will verify that you have no use-after-free bugs, or any other kind of memory-safety bug. The same is not true of (pre-SPARK) Ada, or C, or C++, or BetterC.
It is still WIP, yet to be deployed at large, naturally doesn't cover binary libraries, but it already a very good improvement.
Even if Rust would fail at large scale mainstream adoption, the fact that the community has pickup up Cyclon and ATS ideas to the point that Swift, OCaml, Haskell, Ada, C++, D, Chapel, ParaSail and eventually other communities started to adopt similar ideas, that alone is a major victory to everyone involved in Rust.
Maybe now with Microsoft having some care for Rust, the tooling situation will improve, but right now, even if handicapped, C++ lifetimes are easier to sell in some shops than rebooting the whole stack in Rust.
And in the end they all share the same goal, improved safety in our daily stacks, even the bits we only touch as user.
I think what you're trying to get at is that the borrow checker is based on static lifetimes (that's not the same thing as a "stack-based analysis", by the way). That's true. But that's simply because most lifetimes in practice follow simple static patterns. This is the same observation that motivates RAII in C++. Because heap management tends to follow the same few patterns over and over, judicious use of Rust compiler features and standard libraries can eliminate a lot of problems.
Crossbeam uses "epoch-based memory reclamation," a strategy for maintaining an object shared across threads without either locks or a global garbage collector. The tl;dr of the strategy is that there's a concept of "epochs," and if you update an object, you have to keep the old copy of the object around until the epoch is over. How long an epoch is alive is determined by how slow your readers are.
So, to access some data, you create a Guard object and pass a reference to that Guard object into the functions that access Crossbeam-protected objects. You then get a reference whose lifetime is bounded by the lifetime of your Guard object. (Typically you're going to create the Guard object in your local stack frame, but nobody's stopping you from putting a Guard object on the heap, getting an arbitrarily-long reference to an object, and blocking reclamation for arbitrarily long, if you really want.) You can safely access the data through this reference until its lifetime is over, and other threads won't reclaim the data (i.e., deallocate it from the heap) until your Guard object is gone.
The implementation uses unsafe, but that's not surprising, the implementation of Box itself uses unsafe so it can call malloc/free or whatever your platform equivalent is. What's important is that the safe interface can translate the requirements on paper into requirements that the borrow checker can check, using this Guard object.
std::unique_ptr can't do that. (Also more generally, std::unique_ptr isn't memory-safe - see the example in https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/ .) There's no way in C++ to say "Here's a reference to some data in this unique_ptr, and by the way it's perfectly safe to have more than one reference to it, but you can't hold onto this reference forever because I'd like to deallocate it soon."
We're already finding that the Crossbeam-style guard pattern is helping us express kernel RCU in ways that are safer than what could be done in C. Namely, there are functions that expect to be called inside an RCU read-side critical section but have no way of enforcing that in C other than by adding runtime checks for the current state of RCU. In Rust we can pass the Guard object around and ensure that readers a) create a critical section and b) don't continue to dereference data once they've declared the end of their critical section.
Now, an environment without a GC will use ref counting sometimes but it will regardless of C, Rust, or C++
- can't deal with circular references without user intervention
- storing the reference counter is hard: either it clobbers a whole cache line or it ruins memory alignment
- atomic reference counting has the potential to utterly ruin runtime performance unless it used extremely carefully
And when one cares about performance, creating/destructing hundreds of instances per frame like on reactive approaches, it isn't the best use of CPU cycles.
If someone wants to make the case that SPARK would be a better approach than Rust to writing safe code in the Linux kernel, they should go ahead, but I haven't seen anyone make that case.
> If you now feel like using them, a preview is available in the community 2019 edition of GNAT+SPARK.
"C++ is really mature and there are so many C++ projects and developers!" "Yeah but it has these problems..." "Just use C++17, it solves all that!" ... but C++17 is not the language that is really mature and that all those C++ projects and developers are using.