Prevent GetThreadContext failure (Windows)
(a cherry-pick of commits
3f39ea8,
ab3699da from 'unity-master')
Calls to GetThreadContext may fail. Work around this by putting
access in suspend/resume loop to advance thread past problematic areas
where suspend fails. Capture context in per thread structure at
suspend time rather than retreiving it during the push logic.
* include/private/gcconfig.h [(I386 || X86_64) && (CYGWIN32 || MSWIN32)]
(RETRY_GET_THREAD_CONTEXT): Define macro.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT]
(MAX_SUSPEND_THREAD_RETRIES): Likewise.
* include/private/gcconfig.h [NO_RETRY_GET_THREAD_CONTEXT]
(RETRY_GET_THREAD_CONTEXT): Undefine macro (for test purposes).
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_Thread_Rep): Add
saved_context field; add comment.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_suspend): Define
retry_cnt local variable; set ContextFlags and call GetThreadContext()
after invocation of SuspendThread(); call ResumeThread() and proceed to
SuspendThread() if GetThreadContext() failed (the limit of iterations
is MAX_SUSPEND_THREAD_RETRIES); call Sleep(0) after ResumeThread() or
failed SuspendThread() except for the first 2 iterations.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_push_stack_for):
Declare pcontext local variable (which refers to thread->saved_context);
define context as a macro (to *pcontext) instead of a local variable;
add comment; do not set ContextFlags and do not call GetThreadContext();
undefine context after last use of PUSHn().