diff options
author | Reimer Behrends <behrends@gmail.com> | 2014-10-30 03:42:50 +0100 |
---|---|---|
committer | Reimer Behrends <behrends@gmail.com> | 2014-10-30 03:42:50 +0100 |
commit | 6e3720155adec34f938974be1e7d5df07901bd2d (patch) | |
tree | 506dffd49ffc7dd127e7a6730dcbfd303d78f379 /lib/system/atomics.nim | |
parent | d5b94390dcfe61c645b43305e3673b6c696b39c7 (diff) | |
download | Nim-6e3720155adec34f938974be1e7d5df07901bd2d.tar.gz |
Various atomics fixes for gcc/clang.
Make atomicInc/atomicDec work with clang, too; also, actually import the memory model constants from C rather than relying on the enum matching the C constants by happenstance.
Diffstat (limited to 'lib/system/atomics.nim')
-rw-r--r-- | lib/system/atomics.nim | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 695a5f63e..3ef9d00ec 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -13,24 +13,30 @@ const someGcc = defined(gcc) or defined(llvm_gcc) or defined(clang) when someGcc and hasThreadSupport: - type - AtomMemModel* = enum - ATOMIC_RELAXED, ## No barriers or synchronization. - ATOMIC_CONSUME, ## Data dependency only for both barrier and - ## synchronization with another thread. - ATOMIC_ACQUIRE, ## Barrier to hoisting of code and synchronizes with - ## release (or stronger) - ## semantic stores from another thread. - ATOMIC_RELEASE, ## Barrier to sinking of code and synchronizes with - ## acquire (or stronger) - ## semantic loads from another thread. - ATOMIC_ACQ_REL, ## Full barrier in both directions and synchronizes - ## with acquire loads - ## and release stores in another thread. - ATOMIC_SEQ_CST ## Full barrier in both directions and synchronizes - ## with acquire loads - ## and release stores in all threads. - + type AtomMemModel* = distinct cint + var ATOMIC_RELAXED* {.importc: "__ATOMIC_RELAXED", nodecl.}: AtomMemModel + ## No barriers or synchronization. + var ATOMIC_CONSUME* {.importc: "__ATOMIC_CONSUME", nodecl.}: AtomMemModel + ## Data dependency only for both barrier and + ## synchronization with another thread. + var ATOMIC_ACQUIRE* {.importc: "__ATOMIC_ACQUIRE", nodecl.}: AtomMemModel + ## Barrier to hoisting of code and synchronizes with + ## release (or stronger) + ## semantic stores from another thread. + var ATOMIC_RELEASE* {.importc: "__ATOMIC_RELEASE", nodecl.}: AtomMemModel + ## Barrier to sinking of code and synchronizes with + ## acquire (or stronger) + ## semantic loads from another thread. + var ATOMIC_ACQ_REL* {.importc: "__ATOMIC_ACQ_REL", nodecl.}: AtomMemModel + ## Full barrier in both directions and synchronizes + ## with acquire loads + ## and release stores in another thread. + var ATOMIC_SEQ_CST* {.importc: "__ATOMIC_SEQ_CST", nodecl.}: AtomMemModel + ## Full barrier in both directions and synchronizes + ## with acquire loads + ## and release stores in all threads. + + type TAtomType* = TNumber|pointer|ptr|char ## Type Class representing valid types for use with atomic procs @@ -166,14 +172,14 @@ else: result = p[] proc atomicInc*(memLoc: var int, x: int = 1): int = - when defined(gcc) and hasThreadSupport: + when someGcc and hasThreadSupport: result = atomic_add_fetch(memLoc.addr, x, ATOMIC_RELAXED) else: inc(memLoc, x) result = memLoc proc atomicDec*(memLoc: var int, x: int = 1): int = - when defined(gcc) and hasThreadSupport: + when someGcc and hasThreadSupport: when declared(atomic_sub_fetch): result = atomic_sub_fetch(memLoc.addr, x, ATOMIC_RELAXED) else: @@ -196,7 +202,7 @@ else: # XXX is this valid for 'int'? -when (defined(x86) or defined(amd64)) and (defined(gcc) or defined(llvm_gcc)): +when (defined(x86) or defined(amd64)) and someGcc: proc cpuRelax {.inline.} = {.emit: """asm volatile("pause" ::: "memory");""".} elif (defined(x86) or defined(amd64)) and defined(vcc): |