mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 03:32:32 +00:00
Fixed threading issues for tcc backend
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user