Ben Pfaff wrote: > On Sun, Feb 7, 2021 at 2:57 PM Bruno Haible <br...@clisp.org> wrote: > > (2) Let the signal handler work only on immutable copies of the data > > structure. Whenever the other code manipulates the data structure, > > it creates an immutable copy of it, for the signal handler to use. > > Use an 'asyncsafe-spin' lock through which the signal handler tells > > the other threads to not free that immutable copy while it running. > > > > This is tricky; can it actually be made to work? > > > > Btw, there is an obvious requirement: the technique should use > > malloc/ > > free for memory management, and should not have memory leaks. > > Algorithms that assume a garbage collected memory management are not > > suitable here. > > This makes me think of read-copy-update aka RCU: > https://en.wikipedia.org/wiki/Read-copy-update > https://lwn.net/Articles/262464/ > > In RCU, code that updates the data structure takes a lock, creates and > modifies a copy, and then installs a new pointer to the data structure, > which is otherwise immutable. Readers always access the data structure > through a pointer. Whichever pointer they happen to see when they > read the pointer remains available until they're done with it. > > Using RCU is pretty straightforward once you've done a little of it, but > it takes some reading to understand all of its concepts. It's probably best > for me not to try to explain it all, because I'll surely get some parts of it > wrong. > > Building an RCU implementation isn't necessarily difficult (I have done it, > but the implementation isn't suitable for gnulib). > > There is a liburcu that is under LGPL v2.1: https://liburcu.org/
Thanks for the pointers, Ben. Yes, RCU is the technique I had in mind. So: "can it actually be made to work?" -> Yes. But the implementation of liburcu uses extra signals and a helper thread of its own (or even a helper thread per CPU). I have to rephrase the question: can it be made to work in a straightforward (not necessarily scalability-optimized) way? Bruno