* exceptions.cc (CALL_HANDLER_RETRY_INNER): Rename to reflect different

functionality.
(CALL_HANDLER_RETRY_OUTER): New define.
(setup_handler): Add outer loop to signal handler to try harder to deliver the
signal.
* miscfuncs.cc (yield): Drop priority and use SleepEx() to force thread
rescheduling rather than relying on SwitchToThread().
This commit is contained in:
Christopher Faylor 2011-07-06 16:33:30 +00:00
parent fa0b926af9
commit d1204b6378
3 changed files with 68 additions and 45 deletions

View File

@ -1,3 +1,13 @@
2011-07-06 Christopher Faylor <me.cygwin2011@cgf.cx>
* exceptions.cc (CALL_HANDLER_RETRY_INNER): Rename to reflect different
functionality.
(CALL_HANDLER_RETRY_OUTER): New define.
(setup_handler): Add outer loop to signal handler to try harder to
deliver the signal.
* miscfuncs.cc (yield): Drop priority and use SleepEx() to force thread
rescheduling rather than relying on SwitchToThread().
2011-07-06 Corinna Vinschen <corinna@vinschen.de> 2011-07-06 Corinna Vinschen <corinna@vinschen.de>
* sigproc.cc (wait_sig): Fix debug output. * sigproc.cc (wait_sig): Fix debug output.

View File

@ -32,7 +32,8 @@ details. */
#include "ntdll.h" #include "ntdll.h"
#include "exception.h" #include "exception.h"
#define CALL_HANDLER_RETRY 20 #define CALL_HANDLER_RETRY_OUTER 10
#define CALL_HANDLER_RETRY_INNER 10
char debugger_command[2 * NT_MAX_PATH + 20]; char debugger_command[2 * NT_MAX_PATH + 20];
@ -848,7 +849,9 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
goto out; goto out;
} }
for (int i = 0; i < CALL_HANDLER_RETRY; i++) for (int n = 0; n < CALL_HANDLER_RETRY_OUTER; n++)
{
for (int i = 0; i < CALL_HANDLER_RETRY_INNER; i++)
{ {
tls->lock (); tls->lock ();
if (tls->incyg) if (tls->incyg)
@ -865,13 +868,9 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
HANDLE hth = (HANDLE) *tls; HANDLE hth = (HANDLE) *tls;
/* Suspend the thread which will receive the signal. /* Suspend the thread which will receive the signal.
For Windows 95, we also have to ensure that the addresses returned by If one of these conditions is not true we loop.
GetThreadContext are valid. If the thread is already suspended (which can occur when a program
If one of these conditions is not true we loop for a fixed number of times has called SuspendThread on itself) then just queue the signal. */
since we don't want to stall the signal handler. FIXME: Will this result in
noticeable delays?
If the thread is already suspended (which can occur when a program has called
SuspendThread on itself) then just queue the signal. */
sigproc_printf ("suspending thread"); sigproc_printf ("suspending thread");
res = SuspendThread (hth); res = SuspendThread (hth);
@ -879,7 +878,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
if (res) if (res)
{ {
ResumeThread (hth); ResumeThread (hth);
break; goto out;
} }
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext (hth, &cx)) if (!GetThreadContext (hth, &cx))
@ -890,11 +889,15 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
tls->unlock (); tls->unlock ();
res = ResumeThread (hth); res = ResumeThread (hth);
if (interrupted) if (interrupted)
break; goto out;
sigproc_printf ("couldn't interrupt. trying again."); sigproc_printf ("couldn't interrupt. trying again.");
yield (); yield ();
} }
/* Hit here if we couldn't deliver the signal. Take a more drastic
action before trying again. */
Sleep (1);
}
out: out:
sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not "); sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");

View File

@ -235,11 +235,21 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
return (ssize_t) tot; return (ssize_t) tot;
} }
/* Try hard to schedule another thread. */
void void
yield () yield ()
{ {
for (int i = 0; i < 3; i++) for (int i = 0; i < 2; i++)
SwitchToThread (); {
int prio = GetThreadPriority (GetCurrentThread ());
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
/* MSDN implies that SleepEx(0,...) will force scheduling of other
threads. Unlike SwitchToThread() the documentation does not mention
other cpus so, presumably (hah!), this + using a lower priority will
stall this thread temporarily and cause another to run. */
SleepEx (0, false);
SetThreadPriority (GetCurrentThread (), prio);
}
} }
/* Get a default value for the nice factor. When changing these values, /* Get a default value for the nice factor. When changing these values,