0

I have one atomic integer variable which has a minimum and maximum value. Two threads update the variable, one increments it and the other decrements it. If incrementing would increase the value over the maximum value, the thread blocks and waits for a condition variable. Same thing happens with decrementing when the value hits the minimum. When the value is decremented and the old value is the maximum value, decrementing thread should notify incrementing thread and same thing should happen the other way around when incrementing.

Decrementing function body:

if (atomic_var.load(std::memory_order_acquire) == minimum) {
    std::unique_lock<std::mutex> lk(mutex);
    if (atomic_var.load(std::memory_order_acquire) == minimum) {
        //we have hit the minimum so we have to wait for the other thread to increase the variable
        condition_var.wait(lk, [&]() {
            return atomic_var.load(std::memory_order_relaxed) > minimum;
        });
    }

    //do stuff

    std::atomic_fetch_sub_explicit(&atomic_var, 1u, std::memory_order_release);
    lk.unlock();
    condition_var.notify_all();
    return;
}

//do stuff

if (std::atomic_fetch_sub_explicit(&atomic_var, 1u, std::memory_order_release) == maximum) {
    //we have hit the maximum so the other thread might be waiting
    std::atomic_thread_fence(std::memory_order_acquire);
    condition_var.notify_all();
}
//adding condition_var.notify_all() here fixes the problem but I'm afraid
//that causes a bit too great performance penalty when it could be easily avoided

Which memory orderings I should use for these checks? My current implementation seems to cause dead locks...

Edit: Changing all memory orders to std::memory_order_seq_cst doesn't seem to remove the problem.

latexi95
  • 31
  • 1
  • 2
  • 1) If you use `memory_order_seq_cst` for all of them, do the deadlocks disappear? 2) If that resolves the deadlocks, do you have measurements showing that using `memory_order_seq_cst` is actually causing a significant performance degradation? – T.C. Apr 28 '15 at 05:38
  • @T.C. Using `std::memory_order_seq_cst` doesn't seem to fix the problem. – latexi95 Apr 28 '15 at 10:15
  • Then it's a problem in your design, not in the memory order. – T.C. Apr 28 '15 at 15:20
  • Do you have a very good reason to use anything other than `std::memory_order_seq_cst` and can you prove its correctness? Otherwise, according to answers in [this question](http://stackoverflow.com/questions/9553591/c-stdatomic-what-is-stdmemory-order-and-how-to-use-them), you should not. Having said that, if you still have a deadlock when using `std::memory_order_seq_cst`, then there's a race condition (or other design flaw) somewhere, which we cannot identify for you with only (part of) the source code of the decrementing function body. – Bart van Nierop Apr 30 '15 at 07:58

0 Answers0