Merge pull request #3959 from vegansk/tcc_tls
Fix some threading issues with tcc backend
This commit is contained in:
commit
ab72944a64
3 changed files with 52 additions and 1 deletions
|
|
@ -108,6 +108,8 @@ __clang__
|
||||||
defined __SUNPRO_C || \
|
defined __SUNPRO_C || \
|
||||||
defined __xlC__
|
defined __xlC__
|
||||||
# define NIM_THREADVAR __thread
|
# define NIM_THREADVAR __thread
|
||||||
|
#elif defined __TINYC__
|
||||||
|
# defined NIM_THREADVAR
|
||||||
#else
|
#else
|
||||||
# error "Cannot define NIM_THREADVAR"
|
# error "Cannot define NIM_THREADVAR"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1288,6 +1288,10 @@ const
|
||||||
hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
|
hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
|
||||||
taintMode = compileOption("taintmode")
|
taintMode = compileOption("taintmode")
|
||||||
|
|
||||||
|
when hasThreadSupport and defined(tcc) and not compileOption("tlsEmulation"):
|
||||||
|
# tcc doesn't support TLS
|
||||||
|
{.error: "``--tlsEmulation:on`` must be used when using threads with tcc backend".}
|
||||||
|
|
||||||
when defined(boehmgc):
|
when defined(boehmgc):
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
const boehmLib = "boehmgc.dll"
|
const boehmLib = "boehmgc.dll"
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,51 @@ when defined(windows) and not someGcc:
|
||||||
proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool =
|
proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool =
|
||||||
interlockedCompareExchange(p, cast[int](newValue), cast[int](oldValue)) != 0
|
interlockedCompareExchange(p, cast[int](newValue), cast[int](oldValue)) != 0
|
||||||
# XXX fix for 64 bit build
|
# 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:
|
else:
|
||||||
# this is valid for GCC and Intel C++
|
# this is valid for GCC and Intel C++
|
||||||
proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool
|
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:
|
when (defined(x86) or defined(amd64)) and someGcc:
|
||||||
proc cpuRelax* {.inline.} =
|
proc cpuRelax* {.inline.} =
|
||||||
{.emit: """asm volatile("pause" ::: "memory");""".}
|
{.emit: """asm volatile("pause" ::: "memory");""".}
|
||||||
elif someGcc:
|
elif someGcc or defined(tcc):
|
||||||
proc cpuRelax* {.inline.} =
|
proc cpuRelax* {.inline.} =
|
||||||
{.emit: """asm volatile("" ::: "memory");""".}
|
{.emit: """asm volatile("" ::: "memory");""".}
|
||||||
elif (defined(x86) or defined(amd64)) and defined(vcc):
|
elif (defined(x86) or defined(amd64)) and defined(vcc):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue