[newlib-cygwin] Cygwin: cygtls: Prompt system to switch tasks explicitly in lock()
Takashi Yano
tyan0@sourceware.org
Tue Dec 3 12:23:01 GMT 2024
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=9b7a84d24aa17bdd727eb402cc544fa36f4d812e
commit 9b7a84d24aa17bdd727eb402cc544fa36f4d812e
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Fri Nov 29 17:08:46 2024 +0900
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>
Diff:
---
winsup/cygwin/local_includes/cygtls.h | 19 ++++++++++++++----
winsup/cygwin/scripts/gendef | 36 -----------------------------------
2 files changed, 15 insertions(+), 40 deletions(-)
diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h
index e5a377d6b..efbd557b1 100644
--- a/winsup/cygwin/local_includes/cygtls.h
+++ b/winsup/cygwin/local_includes/cygtls.h
@@ -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)
diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
index 720325fdd..7e14f69cf 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -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
More information about the Cygwin-cvs
mailing list