diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2019-10-04 00:38:28 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2019-10-04 00:38:28 +0300 |
commit | 47873be17352b194bfd42731531fcf6ee68e64dc (patch) | |
tree | 784b329587224683c46b9c38604663dab8b36a6b /win32_threads.c | |
parent | 14deadaddbf84caf4e9a31eb9dfeb3c03e95a599 (diff) | |
download | bdwgc-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.c | 21 |
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 */ } |