2

I am debugging some code using a boost C++ library, which uses Windows InterlockedDecrement and InterlockedIncrement.

In the outputted assembly InterlockedIncrement uses LOCK INC whereas the InterlockedDecrement uses LOCK XADD.

Why do they not both use LOCK XADD?

(This is on Win 7 64, 64-bit compiling and MSVC 11)

intrigued_66
  • 16,082
  • 51
  • 118
  • 189

1 Answers1

4

The INC instruction has a shorter encoding. You could implement both with LOCK XADD, but the code would take more space in memory. They are probably identical once they get turned into uops.

Now, why not use LOCK DEC?

My guess is that the code in question is something like this:

InterlockedIncrement(&refcount);
...

if (InterlockedDecrement(&refcount) == 0)
    ...

This is a common pattern for reference counting. In such a situation, you can't use LOCK DEC because LOCK DEC does not return the resulting value.

// WRONG WRONG WRONG WRONG
InterlockedDecrement(&refcount);
    // <-- another thread might modify refcount here
if (refcount == 0)
    ...
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • So wouldn't it be better to use LOCK DEC? – intrigued_66 Aug 25 '14 at 18:47
  • @mezamorphic: You are probably using the resulting value, forcing it to be `XADD`. – Dietrich Epp Aug 25 '14 at 19:05
  • Why/how does DEC not return the resulting value? I found this link: http://x86.renejeschke.de/html/file_module_x86_id_71.html which says destination = destination - 1, isn't this returning the resulting value? – intrigued_66 Aug 25 '14 at 21:04
  • No, it's just storing the result of the operation back in the same location. If you try to read that location afterwards, another thread might have modified it in the meantime, and you will get an incorrect result. – Dietrich Epp Aug 25 '14 at 21:24