]> granicus.if.org Git - gc/commitdiff
Do not hold GC_fault_handler_lock when in Sleep (Win32)
authorIvan Maidanski <ivmai@mail.ru>
Thu, 3 Oct 2019 21:38:28 +0000 (00:38 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 3 Oct 2019 21:38:28 +0000 (00:38 +0300)
(fix of commits 0c0e4cd0b449eda034)

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().

win32_threads.c

index 6ac42a8c57da56c13346cdd4ce1ebc11cb2724cd..7dfeeb8f89e0f9f91625a244611a7af2f40acd40 100644 (file)
@@ -1276,11 +1276,17 @@ STATIC void GC_suspend(GC_thread t)
 # ifdef RETRY_GET_THREAD_CONTEXT
     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 */
     }