0

In C++ code, but not specific to C++ and could just as easily be expressed in many languages:

atomic<int> counter(0);

// Many threads
counter.fetch_add(1); // lock xadd

// One thread
std::lock_guard<std::mutex> lock(mutex);
counter.exchange(INT_MIN); // lock xchg

Is it possible to have an execution where the xadd reads a value of counter from before the store of INT_MIN, then the store of INT_MIN happens, and the incremented value of counter clobbers INT_MIN - thus it's possible that the counter never goes negative (well assuming it doesn't wrap around, which would be undefined anyway.)

I want to know if that store with xchg can get "lost". If so I really need to use CAS instead of fetch_add. However, I suspect since lock xadd specifically has to protect against losing updates that its execution cannot be interleaved with locked instructions on other threads (at the very least with other lock xadd!)

fuz
  • 88,405
  • 25
  • 200
  • 352
Eloff
  • 20,828
  • 17
  • 83
  • 112
  • 4
    No, that would make the whole point of atomics useless – StenSoft Feb 26 '16 at 14:26
  • Completely puzzled by this code. What's the point of locking the mutex if it is only accessed in one thread? (as per provided code and comments)? – SergeyA Feb 26 '16 at 14:32
  • @SergeyA it was meant to illustrate that only one thread can execute the counter.exchange. You can ignore it. – Eloff Feb 26 '16 at 14:35
  • 2
    If LOCK doesn't work and xchg can get lost then your machine probably wouldn't ever boot up successfully. http://stackoverflow.com/questions/8891067/what-does-the-lock-instruction-mean-in-x86-assembly – James Feb 26 '16 at 14:37
  • @James that matches my intuition – Eloff Feb 26 '16 at 14:54
  • StenSoft's comment is the answer. – BitWhistler Feb 26 '16 at 15:36
  • Incidentally, if I replaced the exchange with .store(INT_MIN, relaxed) does that change anything? – Eloff Feb 26 '16 at 20:57
  • 1
    `if I replaced the exchange with .store(INT_MIN, relaxed) does that change anything?` - Effect on `counter` remains. Effect on other variables may be changed because of lesser memory ordering garantees. (Note, that .exchange() is *read-modify-write* operation, but `.store()` isn't.) Generally, `.exchange()` has a little sence without checking its returning value. – Tsyvarev Feb 29 '16 at 07:21

0 Answers0