Search code examples
c++multithreadingbit-manipulationatomic

Single bit manipulations with guaranteed atomicity


Is there a way to set, clear, test and flip a single bit as an atomic operation in c++? For example bitwise variants to "compare_and_swap".


Solution

  • Manipulating bits atomically requires a compare_exchange RMW to avoid touching other bits in the atomic variable. Testing a bit is not a modifying operation, therefore a load() suffices.

    You will have to add range error checking

    template<typename T, typename OP>
    T manipulate_bit(std::atomic<T> &a, unsigned n, OP bit_op)
    {
        static_assert(std::is_integral<T>::value, "atomic type not integral");
    
        T val = a.load();
        while (!a.compare_exchange_weak(val, bit_op(val, n)));
    
        return val;
    }
    
    auto set_bit = [](auto val, unsigned n) { return val | (1 << n); };
    auto clr_bit = [](auto val, unsigned n) { return val & ~(1 << n); };
    auto tgl_bit = [](auto val, unsigned n) { return val ^ (1 << n); };
    
    
    int main()
    {
        std::atomic<int> a{0x2216};
    
        manipulate_bit(a, 3, set_bit);  // set bit 3
    
        manipulate_bit(a, 7, tgl_bit);  // toggle bit 7
    
        manipulate_bit(a, 13, clr_bit);  // clear bit 13
    
        bool isset = (a.load() >> 5) & 1;  // testing bit 5
    }