Conversation
Today I learned that gawk has a "--debug" command-line argument, and has had for more than ten years. In my defense, I using awk for about 30 years prior to that...
1
6
11

@ljs @paulmckrcu oh, I *loved* abusing `make -j`....

$ make -j 10 emacs

ALL THE LIGHTS LIGHT UP SOLID-ISH...

gawk --debug # today I learnt too... and awk user for 39 years in September.

0
0
1

@paulmckrcu Happened to me, too. On rereading the RSEQ (restartable sequences)* documentation I find out you can set the RSEQ critical regions dynamically. So you can use it to do a wait-free hazard pointer protect that runs about 3x faster than the lock-free version. No loop w/ conditional branch instruction.

There's a couple of other ways to do wait-free hazard pointers but would require changes to retire logic.

1
0
0
@jwseigh Nice! But if I may ask, how does this deal with the possibility that a updater on some other thread concurrently changed the pointer that you are trying to protect?
1
0
0

@paulmckrcu Oh, sorry. I forgot to mention this is used w/ an asymmetric memory barriers, so it will always appear to be atomic to the retire thread which will do a membarrier() before polling the hazard pointers.

protect() is just a load and store apart from setting and clearing rseq_cs value for the restartable sequence.

1
0
1
@jwseigh I thought that membarrier only guaranteed ordering, but perhaps you have a trick that I missed.
1
0
0

@paulmckrcu Like https://pvk.ca/Blog/2020/07/07/flatter-wait-free-hazard-pointers/ but with RSEQ restartable sequence to give you atomic w.r.t. interrupts memory to memory copy. No special hardware instructions. Just Linux and membarrier.

1
0
0
@jwseigh Hmmm, interesting... Does RSEQ now fail in response to vCPU preemption?
1
0
0

@paulmckrcu Not that I am aware of. Is membarrier using vCPU preemption to determine if it occurred?

1
0
0
@jwseigh If the vCPU preemption also blocks the guest-OS-level membarrier() call, perhaps you are OK?
1
0
0

@paulmckrcu No probably not. I'm making unwarranted assumptions. I also don't know if IPI calls trigger RSEQ. I'll just stick with one of the other ways of doing wait-free hazard pointers which just uses standard c++26 and would be totally portable.

1
0
0
@jwseigh As always, much depends on your exact implementation. But what if the RSEQ reader picked up the pointer, took an unrelated long-running interrupt, took (and responded to) the membarrier IPI, then took another unrelated long-running interrupt? I do not believe that this would cause RSEQ to retry (though I might be missing something).

In that scenario, how is the updater to know that it should avoid reclaiming the object whose pointer the RSEQ reader will eventually store into its hazard pointer?

(I get the blog post: If you can uninterruptibly load and store the pointer, then membarrier() will either force the reader to see the new pointer or force the updater to see the updated hazard pointer.
I do not understand how your RSEQ trick works. Not yet, anyway.)
1
0
0

@paulmckrcu I was making assumptions about how membarrier was implemented. If it was using RCU it would probably work, not so much for the other implementations.

Anyway, I have a wait-free epoch based reclamation implementation that is easier to work with and has the ability to control reclaim granularity.

1
0
0
@jwseigh This stuff is tricky, and thank you for introducing me to the memory-to-memory single-instruction copy trick for Hazard Pointers.
1
0
0

@paulmckrcu Yes, very tricky. Apparently I mentioned you could do it with a MVC instruction 20 years ago, https://groups.google.com/g/comp.programming.threads/c/XU6BtGNSkF0/m/AmWXvkGn3DAJ, but I have absolutely no memory of that. So I "reinvented" it a short while back, then convinced myself it wouldn't work, and then came across that other article.

0
0
0