4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-13 04:29:09 +08:00

Cygwin: cygtls: Prompt system to switch tasks explicitly in lock()

This patch calls Sleep(0) in the wait loop in lock() to increase the
chance of being unlocked in other threads. The lock(), unlock() and
locked() are moved from sigfe.s to cygtls.h so that allows inline
expansion.

Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256744.html
Fixes: 61522196c715 ("* Merge in cygwin-64bit-branch.")
Reported-by: Christian Franke <Christian.Franke@t-online.de>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
Takashi Yano 2024-11-29 17:08:46 +09:00
parent a82bf55908
commit 9b7a84d24a
2 changed files with 15 additions and 40 deletions

View File

@ -197,7 +197,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
int current_sig;
unsigned incyg;
unsigned spinning;
unsigned stacklock;
volatile unsigned stacklock;
__tlsstack_t *stackptr;
__tlsstack_t stack[TLS_STACK_SIZE];
unsigned initialized;
@ -225,9 +225,20 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
int call_signal_handler ();
void remove_wq (DWORD);
void fixup_after_fork ();
void lock ();
void unlock ();
bool locked ();
void lock ()
{
while (InterlockedExchange (&stacklock, 1))
{
#ifdef __x86_64__
__asm__ ("pause");
#else
#error unimplemented for this target
#endif
Sleep (0);
}
}
void unlock () { stacklock = 0; }
bool locked () { return !!stacklock; }
HANDLE get_signal_arrived (bool wait_for_lock = true)
{
if (!signal_arrived)

View File

@ -322,42 +322,6 @@ _ZN7_cygtls3popEv:
ret
.seh_endproc
# _cygtls::lock
.global _ZN7_cygtls4lockEv
.seh_proc _ZN7_cygtls4lockEv
_ZN7_cygtls4lockEv:
pushq %r12
.seh_pushreg %r12
.seh_endprologue
movq %rcx,%r12
1: movl \$1,%r11d
xchgl %r11d,_cygtls.stacklock_p(%r12) # try to acquire lock
testl %r11d,%r11d
jz 2f
pause
jmp 1b
2: popq %r12
ret
.seh_endproc
# _cygtls::unlock
.global _ZN7_cygtls6unlockEv
.seh_proc _ZN7_cygtls6unlockEv
_ZN7_cygtls6unlockEv:
.seh_endprologue
decl _cygtls.stacklock_p(%rcx) # release lock
ret
.seh_endproc
# _cygtls::locked
.global _ZN7_cygtls6lockedEv
.seh_proc _ZN7_cygtls6lockedEv
_ZN7_cygtls6lockedEv:
.seh_endprologue
movl _cygtls.stacklock_p(%rcx),%eax
ret
.seh_endproc
.seh_proc stabilize_sig_stack
stabilize_sig_stack:
pushq %r12