Asymmetric Fences? While browsing through Folly’s synchronization primitives to study up on concurrency concepts, one familiar-looking name in the codebase caught my attention: Asymmetric Thread Fence. I already knew what std::atomic_thread_fence is meant to achieve, but what does this construct do? And what exactly is asymmetric about it? That question led me down an interesting rabbit hole: ...
Strongly Happens Before? It started innocently enough. I just wanted to brush up on C++ memory orderings. It’s been a while since I last stared into the abyss of std::atomic, so I figured, why not revisit some good ol’ std::memory_order mayhem? Then I saw it. Strongly happens before. Wait, what? When did we get a stronger version of happens before? Turns out, it has been there for quite some...
Quick Note: If you’re into the nitty-gritty details, be sure to check out Part 1 and Part 2. But if you’re here for practical advice, welcome to Part 3! Best Practices As promised in the Part 2, here are the three key rules to keep in mind when dealing with low-level object manipulation: Always use arrays of std::byte or unsigned char as memory buffers instead of char. Always check whet...
Quick Note: If you haven’t read Part 1, why are you here? Turn back and read Part 1! Looking Back At Our Fix In our previous post, we came up with the following implementation: template<std::size_t N> struct MyAllocator { std::byte data[N]; void* p; std::size_t sz; MyAllocator() : p(data), sz(N) {} // Note: Only well-defined for implicit-lifetime types template&...