Altick
Altick

Reputation: 11

Lock free counter for two atomic ints

I want to implement a lock-free structure, that returns values strictly in an ascending order. I have 2 atomic int's and want to make long from them, so the idea is to firstly increment first memory chunk, and then, once it reaches max value for int, increment the second by one and set first to 0.

I've managed to write this code, but it is not working due to sometime making an ABA-like problem (memory first set to 0 by some thread, while other start to read it and get the wrong value, without incrementing second memory)

    unsigned int second = secondmem -> load(), first = first = firstmem->load();
    while (true) {
        unsigned int nfirst = first + 1, nsecond = second;
        if (first == UINT32_MAX) {
            nfirst = 0;
            nsecond = second + 1;
        }
        if (!secondmem->compare_exchange_strong(second, nsecond)) {
            continue;
        }
        if (!firstmem->compare_exchange_strong(first, nfirst)) {
            continue;
        }
        if (secondmem->compare_exchange_strong(second, second)) {
            return convertInts(nsecond, nfirst);
        }
    }

The structure definition

struct MyStruct {
    std::atomic_uint32_t *firstmem, *secondmem;

    MyStruct(std::atomic_uint32_t & mem1, std::atomic_uint32_t & mem2)  {
        firstmem = &mem1;
        secondmem = &mem2;
    }

    unsigned long long get();

Upvotes: 1

Views: 131

Answers (0)

Related Questions