summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorRuslan Mustakov <endragor@users.noreply.github.com>2017-05-12 16:24:45 +0700
committerAndreas Rumpf <rumpf_a@web.de>2017-05-12 11:24:45 +0200
commit77cadd07f9079ef9c5f3907cbe273b075aa1f76d (patch)
treee482251559a1f695f4dcc4e487396bf6b36d38ff /lib
parent2e420dfa382dc5af3a225a7b073da2d0eb3d899f (diff)
downloadNim-77cadd07f9079ef9c5f3907cbe273b075aa1f76d.tar.gz
Fix atomicInc under vcc, C++, amd64 (#5809)
Also, fixed inconsistent behaviour of atomicInc on vcc. Previously
it would return the old value, while it must return the new value.

Fixes: #5808
Diffstat (limited to 'lib')
-rw-r--r--lib/system/atomics.nim20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim
index 3a43729dc..885b01621 100644
--- a/lib/system/atomics.nim
+++ b/lib/system/atomics.nim
@@ -165,8 +165,22 @@ when someGcc and hasThreadSupport:
 
   template fence*() = atomicThreadFence(ATOMIC_SEQ_CST)
 elif defined(vcc) and hasThreadSupport:
-  proc addAndFetch*(p: ptr int, val: int): int {.
-    importc: "_InterlockedExchangeAdd", header: "<intrin.h>".}
+  when defined(cpp):
+    when sizeof(int) == 8:
+      proc addAndFetch*(p: ptr int, val: int): int {.
+        importcpp: "_InterlockedExchangeAdd64(static_cast<NI volatile *>(#), #)",
+        header: "<intrin.h>".}
+    else:
+      proc addAndFetch*(p: ptr int, val: int): int {.
+        importcpp: "_InterlockedExchangeAdd(static_cast<NI volatile *>(#), #)",
+        header: "<intrin.h>".}
+  else:
+    when sizeof(int) == 8:
+      proc addAndFetch*(p: ptr int, val: int): int {.
+        importc: "_InterlockedExchangeAdd64", header: "<intrin.h>".}
+    else:
+      proc addAndFetch*(p: ptr int, val: int): int {.
+        importc: "_InterlockedExchangeAdd", header: "<intrin.h>".}
 
   proc fence*() {.importc: "_ReadWriteBarrier", header: "<intrin.h>".}
 
@@ -180,6 +194,7 @@ proc atomicInc*(memLoc: var int, x: int = 1): int =
     result = atomic_add_fetch(memLoc.addr, x, ATOMIC_RELAXED)
   elif defined(vcc) and hasThreadSupport:
     result = addAndFetch(memLoc.addr, x)
+    inc(result, x)
   else:
     inc(memLoc, x)
     result = memLoc
@@ -192,6 +207,7 @@ proc atomicDec*(memLoc: var int, x: int = 1): int =
       result = atomic_add_fetch(memLoc.addr, -x, ATOMIC_RELAXED)
   elif defined(vcc) and hasThreadSupport:
     result = addAndFetch(memLoc.addr, -x)
+    dec(result, x)
   else:
     dec(memLoc, x)
     result = memLoc