On Fri, Apr 16, 2021 at 04:19:07PM +0200, Peter Zijlstra wrote: > Does this also not prohibit constructs where modification must be done > while holding two locks, but reading can be done while holding either > lock? I don't believe it does. Remember that we have full control of the abstractions, so we can (and will when the need arises) build an abstraction that provides the functionality you describe. For the read path, we can have functions that return a read-only guard (which is the gateway to the data in Rust) when locking either of the locks, or when showing evidence that either lock is already locked (i.e., by temporarily transferring ownership of another guard). Note that this is another area where Rust offers advantages: read-only guards (in C, if you take a read lock, nothing prevents you from making changes to fields you should only be allowed to read); and the ability to take temporary ownership, giving it back even within the same function. Similarly, to access a mutable guard, you'd have to show evidence that both locks are held. > That's a semi common scheme in the kernel, but not something that's > expressible by, for example, the Java sync keyword. > > It also very much doesn't work for RCU, where modification must be done > under a lock, but access is done essentially lockless. Why not? RCU is a lock -- it may have zero cost in most (all?) architectures on the read path, but it is a lock. We can model access to variables/fields protected by it just like any other lock, with the implementation of lock/unlock optimizing to no-ops on the read path where possible. In fact, this is also an advantage of Rust. It would *force* developers to lock/unlock the RCU lock before they can access the protected data. > I would much rather have a language extention where we can associate > custom assertions with variable access, sorta like a sanitizer: > > static inline void assert_foo_bar(struct foo *f) > { > lockdep_assert_held(&f->lock); > } > > struct foo { > spinlock_t lock; > int bar __assert__(assert_foo_bar); > }; > > Such things can be optional and only enabled for debug builds on new > compilers. These would be great, but would still fall short of the compile-time guaranteed safety that Rust offers in these cases. > C does indeed not have the concept of ownership, unlike modern C++ I > think. But I would much rather see a C language extention for that than > go Rust. > > This would mean a far more agressive push for newer C compilers than > we've ever done before, but at least it would all still be a single > language. Convertion to the new stuff can be done gradually and where > it makes sense and new extentions can be evaluated on performance impact > etc. I encourage you to pursue this. We'd all benefit from better C. I'd be happy to review and provide feedback on proposed extensions that are deemed equivalent/better than what Rust offers. My background is also in C. I'm no Rust fanboy, I'm just taking what I think is a pragmatic view of the available options.