summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-10-13 01:59:58 +0200
committerAraq <rumpf_a@web.de>2012-10-13 01:59:58 +0200
commit4dde2137f7a63e9325efdcb9e87ce0c4ac26886f (patch)
tree80d9399701f833afb94bab88ad8c3a711ddf466d /lib
parentffcbe19cd8db0fa5a5538759c6b41cd29b6d2a38 (diff)
parenta9da8eba06f5fb5992b2a537a8872d5e64ee0cdb (diff)
downloadNim-4dde2137f7a63e9325efdcb9e87ce0c4ac26886f.tar.gz
Merge branch 'master' of github.com:Araq/Nimrod
Diffstat (limited to 'lib')
-rwxr-xr-xlib/system/atomics.nim34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim
index 127a8637f..623f8d0d2 100755
--- a/lib/system/atomics.nim
+++ b/lib/system/atomics.nim
@@ -40,3 +40,37 @@ proc atomicDec(memLoc: var int, x: int = 1): int =
     dec(memLoc, x)
     result = memLoc  
 
+
+# atomic compare and swap (CAS) funcitons to implement lock-free algorithms
+
+when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
+  proc compareAndSwap*[T: ptr|ref|pointer](mem: var T, expected: T, newValue: T): bool {.nodecl, 
+      importc: " __sync_bool_compare_and_swap".}
+    ## Returns true if successfully set value at mem to newValue when value
+    ## at mem == expected
+      
+elif defined(windows) and hasThreadSupport:
+    proc InterlockedCompareExchangePointer(mem: ptr pointer,
+      newValue: pointer, comparand: pointer) : pointer {.nodecl, 
+        importc: "InterlockedCompareExchangePointer", header:"windows.h".}
+
+
+    proc compareAndSwap*[T: ptr|ref|pointer](mem: var T, 
+      expected: T, newValue: T): bool {.inline.}=
+      ## Returns true if successfully set value at mem to newValue when value
+      ## at mem == expected
+      return InterlockedCompareExchangePointer(addr(mem), 
+        newValue, expected) == expected
+    
+elif not hasThreadSupport:
+  proc compareAndSwap*[T: ptr|ref|pointer](mem: var T, 
+    expected: T, newValue: T): bool {.inline.} =
+      ## Returns true if successfully set value at mem to newValue when value
+      ## at mem == expected
+      var oldval = mem
+      if oldval == expected:
+        mem = newValue
+        return true
+      return false
+
+