mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-29 16:18:43 +08:00
win32: avoid Interlocked imports for tcc arm64
Windows/arm64 exposes Interlocked* operations as compiler intrinsics rather than kernel32 exports. When tcc -run self-compiles tcc.c, calls to InterlockedCompareExchange or InterlockedExchange can therefore remain as unresolved imports in the in-memory linker. Route the TinyCC arm64 path through the existing __atomic helpers while keeping Interlocked* for other Windows compilers. The compile-lock initialization state machine remains unchanged.
This commit is contained in:
parent
601a088214
commit
904e95cbdf
40
tcc.h
40
tcc.h
@ -1930,12 +1930,46 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
|
|||||||
#if CONFIG_TCC_SEMLOCK
|
#if CONFIG_TCC_SEMLOCK
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
typedef struct { volatile LONG init; CRITICAL_SECTION cs; } TCCSem;
|
typedef struct { volatile LONG init; CRITICAL_SECTION cs; } TCCSem;
|
||||||
|
#if defined __TINYC__ && (defined __aarch64__ || defined __arm64__)
|
||||||
|
/* Windows/arm64 Interlocked* names are compiler intrinsics, not
|
||||||
|
kernel32 exports, so tcc -run must not emit calls to them. */
|
||||||
|
# define TCC_SEM_USE_ATOMICS 1
|
||||||
|
enum { TCC_SEM_ATOMIC_SEQ_CST = 5 };
|
||||||
|
#endif
|
||||||
|
static inline LONG tcc_sem_cmpxchg(volatile LONG *ptr, LONG val, LONG cmp) {
|
||||||
|
#ifdef TCC_SEM_USE_ATOMICS
|
||||||
|
LONG old = cmp;
|
||||||
|
__atomic_compare_exchange((LONG *)ptr, &old, &val, 0,
|
||||||
|
TCC_SEM_ATOMIC_SEQ_CST,
|
||||||
|
TCC_SEM_ATOMIC_SEQ_CST);
|
||||||
|
return old;
|
||||||
|
#else
|
||||||
|
return InterlockedCompareExchange(ptr, val, cmp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static inline void tcc_sem_store(volatile LONG *ptr, LONG val) {
|
||||||
|
#ifdef TCC_SEM_USE_ATOMICS
|
||||||
|
__atomic_store((LONG *)ptr, &val, TCC_SEM_ATOMIC_SEQ_CST);
|
||||||
|
#else
|
||||||
|
InterlockedExchange(ptr, val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static inline LONG tcc_sem_load(volatile LONG *ptr) {
|
||||||
|
#ifdef TCC_SEM_USE_ATOMICS
|
||||||
|
LONG val;
|
||||||
|
__atomic_load((LONG *)ptr, &val, TCC_SEM_ATOMIC_SEQ_CST);
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
return InterlockedCompareExchange(ptr, 0, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
static inline void wait_sem(TCCSem *p) {
|
static inline void wait_sem(TCCSem *p) {
|
||||||
if (InterlockedCompareExchange(&p->init, 1, 0) == 0) {
|
if (tcc_sem_cmpxchg(&p->init, 1, 0) == 0) {
|
||||||
InitializeCriticalSection(&p->cs);
|
InitializeCriticalSection(&p->cs);
|
||||||
InterlockedExchange(&p->init, 2);
|
tcc_sem_store(&p->init, 2);
|
||||||
} else {
|
} else {
|
||||||
while (InterlockedCompareExchange(&p->init, 2, 2) != 2)
|
/* On tcc/arm64, __atomic_load maps to the acquire helper path. */
|
||||||
|
while (tcc_sem_load(&p->init) != 2)
|
||||||
Sleep(0);
|
Sleep(0);
|
||||||
}
|
}
|
||||||
EnterCriticalSection(&p->cs);
|
EnterCriticalSection(&p->cs);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user