summaryrefslogtreecommitdiff
path: root/win32_threads.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2019-10-04 00:38:28 +0300
committerIvan Maidanski <ivmai@mail.ru>2019-10-04 00:38:28 +0300
commit47873be17352b194bfd42731531fcf6ee68e64dc (patch)
tree784b329587224683c46b9c38604663dab8b36a6b /win32_threads.c
parent14deadaddbf84caf4e9a31eb9dfeb3c03e95a599 (diff)
downloadbdwgc-47873be17352b194bfd42731531fcf6ee68e64dc.tar.gz
Do not hold GC_fault_handler_lock when in Sleep (Win32)
(fix of commits 0c0e4cd0b, 449eda034) Also, reduce a period between GetExitCodeThread and SuspendThread. * win32_threads.c [DEBUG_THREADS] (GC_suspend): Call GC_log_printf() before UNPROTECT_THREAD(). * win32_threads.c [DEBUG_THREADS && !MSWINCE] (GC_suspend): Call GC_acquire_dirty_lock() before GetExitCodeThread(); call GC_release_dirty_lock() immediately if GetExitCodeThread() failed. * win32_threads.c [MSWINCE || RETRY_GET_THREAD_CONTEXT] (GC_suspend): Wrap Sleep() call with GC_release/acquire_dirty_lock().
Diffstat (limited to 'win32_threads.c')
-rw-r--r--win32_threads.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/win32_threads.c b/win32_threads.c
index 6ac42a8c..7dfeeb8f 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -1277,10 +1277,16 @@ STATIC void GC_suspend(GC_thread t)
int retry_cnt = 0;
# define MAX_SUSPEND_THREAD_RETRIES (1000 * 1000)
# endif
+
+# ifdef DEBUG_THREADS
+ GC_log_printf("Suspending 0x%x\n", (int)t->id);
+# endif
UNPROTECT_THREAD(t);
+ GC_acquire_dirty_lock();
# ifndef MSWINCE
if (GetExitCodeThread(t -> handle, &exitCode) &&
exitCode != STILL_ACTIVE) {
+ GC_release_dirty_lock();
# ifdef GC_PTHREADS
t -> stack_base = 0; /* prevent stack from being pushed */
# else
@@ -1292,14 +1298,14 @@ STATIC void GC_suspend(GC_thread t)
return;
}
# endif
-# ifdef DEBUG_THREADS
- GC_log_printf("Suspending 0x%x\n", (int)t->id);
-# endif
- GC_acquire_dirty_lock();
+
# ifdef MSWINCE
/* SuspendThread() will fail if thread is running kernel code. */
- while (SuspendThread(THREAD_HANDLE(t)) == (DWORD)-1)
+ while (SuspendThread(THREAD_HANDLE(t)) == (DWORD)-1) {
+ GC_release_dirty_lock();
Sleep(10); /* in millis */
+ GC_acquire_dirty_lock();
+ }
# elif defined(RETRY_GET_THREAD_CONTEXT)
for (;;) {
if (SuspendThread(t->handle) != (DWORD)-1) {
@@ -1317,8 +1323,11 @@ STATIC void GC_suspend(GC_thread t)
if (ResumeThread(t->handle) == (DWORD)-1)
ABORT("ResumeThread failed");
}
- if (retry_cnt > 1)
+ if (retry_cnt > 1) {
+ GC_release_dirty_lock();
Sleep(0); /* yield */
+ GC_acquire_dirty_lock();
+ }
if (++retry_cnt >= MAX_SUSPEND_THREAD_RETRIES)
ABORT("SuspendThread loop failed"); /* something must be wrong */
}