diff options
author | Anatoly Galiulin <galiulin.anatoly@gmail.com> | 2016-03-04 13:01:17 +0600 |
---|---|---|
committer | Anatoly Galiulin <galiulin.anatoly@gmail.com> | 2016-03-10 17:45:11 +0600 |
commit | 09687717857ee2c30661aed63e3bac2fc44cf388 (patch) | |
tree | 1ca7c5feff3fb1a71be9107e42f716ffdaba35fb /lib/system | |
parent | 7281b66a4f91ec7f8124353835c627362dac23c1 (diff) | |
download | Nim-09687717857ee2c30661aed63e3bac2fc44cf388.tar.gz |
Fixed threading issues for tcc backend
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/atomics.nim | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 158fe91bc..a79dcb152 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -197,6 +197,51 @@ when defined(windows) and not someGcc: proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool = interlockedCompareExchange(p, cast[int](newValue), cast[int](oldValue)) != 0 # XXX fix for 64 bit build +elif defined(tcc) and not defined(windows): + when defined(amd64): + {.emit:""" +static int __tcc_cas(int *ptr, int oldVal, int newVal) +{ + unsigned char ret; + __asm__ __volatile__ ( + " lock\n" + " cmpxchgq %2,%1\n" + " sete %0\n" + : "=q" (ret), "=m" (*ptr) + : "r" (newVal), "m" (*ptr), "a" (oldVal) + : "memory"); + + if (ret) + return 0; + else + return 1; +} +""".} + else: + assert sizeof(int) == 4 + {.emit:""" +static int __tcc_cas(int *ptr, int oldVal, int newVal) +{ + unsigned char ret; + __asm__ __volatile__ ( + " lock\n" + " cmpxchgl %2,%1\n" + " sete %0\n" + : "=q" (ret), "=m" (*ptr) + : "r" (newVal), "m" (*ptr), "a" (oldVal) + : "memory"); + + if (ret) + return 0; + else + return 1; +} +""".} + + proc tcc_cas(p: ptr int; oldValue, newValue: int): bool + {.importc: "__tcc_cas", nodecl.} + proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool = + tcc_cas(cast[ptr int](p), cast[int](oldValue), cast[int](newValue)) else: # this is valid for GCC and Intel C++ proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool @@ -207,7 +252,7 @@ else: when (defined(x86) or defined(amd64)) and someGcc: proc cpuRelax* {.inline.} = {.emit: """asm volatile("pause" ::: "memory");""".} -elif someGcc: +elif someGcc or defined(tcc): proc cpuRelax* {.inline.} = {.emit: """asm volatile("" ::: "memory");""".} elif (defined(x86) or defined(amd64)) and defined(vcc): |