[1] https://en.wikipedia.org/wiki/Read-copy-update if you just want to know what it is and http://www.rdrop.com/users/paulmck/RCU/rclock_OLS.2001.05.01... if you want the good stuff
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p25...
I hope we get a next generation of systems languages with improved memory models that can actually express these things directly.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p00... https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p01... https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p04... https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p07...
A lot of the problems center around the reliance on data dependencies for ordering, and the difficulty of expressing these requirements in a manner that is compatible with separate compilation and compiler optimizations.
Assume: a = 1, p = &a, b = 0
Thr. 1 | Thr. 2
b = 1 |
memory_barrier | i = *p
p = &b |
The result can be i = 0Even though b=1 happens "before" p=&b within Thread 1, it is seen as happening after it by Thread 2. To overcome this, Thread 2 needs a barrier between the load of p from memory and the indirect load that assigns to i. Practically no other architectures have that quirk, and it only happens on Alpha because of its two separate cache banks.
Unfortunately, it has turned out to be infeasible to give memory_order_consume a proper weak semantics setting it apart from memory_order_acquire, given e.g. how common it is for indirections to be altered by compiler optimizations. So Ordering::Consume does not, as of yet, exist in Rust.
What do you mean exactly? Of course the required remote memory barrier need to be a primitive as it is provided by the OS, and ultimately the hardware, but AFAIK the asymmetric synchronization needed by RCU can be modelled within the C++ as a signal and a atomic signal fence.
To work around this flaw, you can use inline assembly, implementation-specific "compiler-only" barriers, etc. but that's outside of the language. It also forces the compiler to be much more pessimistic about optimizations than is actually necessary to preserve dependency ordering.
https://mirrors.edge.kernel.org/pub/linux/kernel/people/paul...
The book's called "atomics and locks". What language doesn't already have those? If I'm touching those, doesn't that mean I'm already trying to reimplement my own concurrency-safety mechanisms?
Howabout Rust implements my favourite concurrency-related safety mechanisms, so I don't need to ever know about atomics or locks.
Rust got scoped threads (again), that's a rather nice safe concurrency feature, a way to say "This thread shall only live during this object's lifetime". For example you can give a new HttpConnection to a scoped thread, knowing that Rust ensures the thread ends before the HttpConnection ceases to exist. Before scoped threads Rust wouldn't let you (safely) make threads which use outside objects with a finite lifespan, as it can't be sure the thread won't touch an object which no longer exists.
But this sort of book is more aimed at people who are interested in the details you apparently don't care about (or don't want to care about). Somebody has to know how it works to build the higher level mechanisms you desire.
As you would expect, Rust does have concurrency primitives, which is why the book shows you how they are implemented and why they are implemented they way they are. In doing so it also teaches you how to do low level things for when you can't use the language provided primitives, like if you're interacting with FFI boundaries or implementing your own lockless datastructure.
Your comment is like seeing a link to "Learning Rust With Entirely Too Many Linked Lists" and reacting with "what language doesn't have linked lists?"
Edit: I see that you might have meant "why would I reimplement Rust's atomic primitives in another language". Well, some documentation is needed for anyone that will have to implement those language primitives, in existing languages (because there are undressed needs) or in new ones. More documentation and explanation of tricky concepts is good.
How on earth are you doing concurrency without touching these two key primitives at some point? Lots of lockless?
using one of the many higher level concepts/frameworks available.
- actor model
- fork join
- CSP
etc.
> How on earth are you doing concurrency without touching these two key primitives
and not how to write high level concurrency frameworks.
I wouldn't trust very much a concurrency framework written by someone who just learned about locks and atomics on a book.
I wouldn't even trust myself to write low level concurrent code using locks and atomics.
I have 26 years of experience as a programmer and if there's something I've learned is that low level concurrency is really hard to get right, even when you perfectly understand the underlying concepts, and it's best left to real experts that dedicated their career to it.
> Which brings us to another group of potential readers, the Rust skeptics. While I do believe that most Rust skeptics are doing the community a valuable service by pointing out opportunities for improvement, all but the most Rust-savvy of skeptics would benefit from reading this book. If nothing else, doing so would enable them to provide sharper and better-targeted criticisms.
> Then there are those dyed-in-the-wool non-Rust developers who would prefer to implement Rust's concurrency-related safety mechanisms in their own favorite language. This book will give them a deeper understanding of the Rust mechanisms that they would like to replicate, or, better yet, improve upon.
https://marabos.nl/atomics/foreword.html