Fixed threading issues for tcc backend

This commit is contained in:
Anatoly Galiulin
2016-03-04 13:01:17 +06:00
parent 7281b66a4f
commit 0968771785
3 changed files with 52 additions and 1 deletions

View File

@@ -108,6 +108,8 @@ __clang__
defined __SUNPRO_C || \
defined __xlC__
# define NIM_THREADVAR __thread
#elif defined __TINYC__
# defined NIM_THREADVAR
#else
# error "Cannot define NIM_THREADVAR"
#endif

View File

@@ -1288,6 +1288,10 @@ const
hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own
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(windows):
const boehmLib = "boehmgc.dll"

View File

@@ -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):