* 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:
parent
fa0b926af9
commit
d1204b6378
|
@ -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.
|
||||||
|
|
|
@ -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 ");
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue