[newlib-cygwin/cygwin-3_5-branch] Cygwin: cygtls: Prompt system to switch tasks explicitly in lock()
Corinna Vinschen
corinna@sourceware.org
Fri Dec 6 10:47:23 GMT 2024
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=da6d5f838c19aeaacbda85b6fe3f27c022d12f1c
commit da6d5f838c19aeaacbda85b6fe3f27c022d12f1c
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
AuthorDate: Fri Nov 29 17:08:46 2024 +0900
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Fri Dec 6 11:41:52 2024 +0100
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>
(cherry picked from commit 9b7a84d24aa17bdd727eb402cc544fa36f4d812e)
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 f967bb9cc272..23ef1701a5fe 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 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 fae7a7f313d8..bb87ab55e557 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -312,42 +312,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