https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=aecd8077bfe384a4544e1774d713aff15534d8d4

commit aecd8077bfe384a4544e1774d713aff15534d8d4
Author: Takashi Yano <takashi.y...@nifty.ne.jp>
Date:   Thu Dec 12 15:03:39 2024 +0900

    Cygwin: signal: Fix high load when retrying to process pending signal
    
    The commit e10f822a2b39 has a problem that CPU load gets high if
    pending signal is not processed successfully for a long time.
    With this patch, wait_sig() calls Sleep(1), rather than yield(),
    if the pending signal has not been processed successfully for a
    predetermined time to prevent CPU from high load.
    
    Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256884.html
    Fixes: e10f822a2b39 ("Cygwin: signal: Handle queued signal without explicit 
__SIGFLUSH")
    Reported-by: 凯夏 <walke...@gmail.com>
    Reviewed-by: Corinna Vinschen <cori...@vinschen.de>
    Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>
    (cherry picked from commit 1d1451ccd2a6c0f0146ddee68f386061b69863c0)

Diff:
---
 winsup/cygwin/sigproc.cc | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 1ab33fc3c..58a9e5a31 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1346,6 +1346,13 @@ wait_sig (VOID *)
   hntdll = GetModuleHandle ("ntdll.dll");
 
   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL);
+
+  /* GetTickCount() here is enough because GetTickCount() - t0 does
+     not overflow until 49 days psss. Even if GetTickCount() overflows,
+     GetTickCount() - t0 returns correct value, since underflow in
+     unsigned wraps correctly. Pending a signal for more thtn 49
+     days would be noncense. */
+  DWORD t0 = GetTickCount ();
   for (;;)
     {
       DWORD nb;
@@ -1355,7 +1362,7 @@ wait_sig (VOID *)
       else if (sigq.start.next
               && PeekNamedPipe (my_readsig, NULL, 0, NULL, &nb, NULL) && !nb)
        {
-         yield ();
+         Sleep (GetTickCount () - t0 > 10 ? 1 : 0);
          pack.si.si_signo = __SIGFLUSH;
        }
       else if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL))
@@ -1365,6 +1372,8 @@ wait_sig (VOID *)
          system_printf ("garbled signal pipe data nb %u, sig %d", nb, 
pack.si.si_signo);
          continue;
        }
+      if (pack.si.si_signo != __SIGFLUSH)
+       t0 = GetTickCount ();
 
       sigq.retry = false;
       /* Don't process signals when we start exiting */

Reply via email to