Use a membarrier inside a docker container Use a membarrier inside a docker container docker docker

Use a membarrier inside a docker container


The membarrier syscall isn't on Docker seccomp whitelist by default so you need to pass a modified profile to your docker run command if you want to use it:

docker run --security-opt seccomp=/path/to/seccomp/profile.json myimage

I am not sure why isn't whitelisted, you could ask the docker devs if this is a bug or a expected configuration.


And for the main code to be able to reliably read that variable, I need to use a membarrier both in the handler and in the main code.

No, just make it volatile sig_atomic_t. ISO C guarantees that will make your code work without needing to write any explicit barriers in the source. (Basically like lock-free _Atomic with mo_relaxed ordering, except ordered wrt. other volatile accesses.)

And if you did need a memory barrier, you don't need a membarrier system call, just asm("" ::: "memory") to force a store or load to happen at least once in a loop.

membarrier() might be useful if you had another thread doing weakly-ordered loads from memory, but which couldn't be optimized away (hoisted out of a loop). Then membarrier() could maybe turn that relaxed load on another core into effectively an acquire load, if you do it between two stores in a producer thread.

Since you're already using a compile-time full barrier in the reader (to stop the non-volatile load from being hoisted out of the loop), and checking an exit_now or keep_running flag has no ordering wrt. other code, you don't need that.


ISO C only guarantees anything for volatile sig_atomic_t, not plain sig_atomic_t (which is usually just int) in the first place. The only reason to use sig_atomic_t is if you're using it with volatile.

In practice, volatile int will even be visible to other threads, not just between a signal handler and the thread that paused to run the signal handler. (Because real C implementations run on cache-coherent hardware, and don't do hardware race detection, etc.) But at that point you're just rolling your own lock-free atomics and should instead use _Atomic int. See also https://electronics.stackexchange.com/questions/387181/mcu-programming-c-o2-optimization-breaks-while-loop/387478#387478 for atomicity between a single thread and an interrupt (or signal) handler.

And see also When to use volatile with multi threading? - basically never, use C11 _Atomic from stdatomic.h. My answer explains why it does work in practice, and exactly what happens.