[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