Avoid busy waiting in mark_thread while GC_parallel is false
authorIvan Maidanski <ivmai@mail.ru>
Tue, 22 Aug 2017 05:56:31 +0000 (08:56 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 22 Aug 2017 05:56:31 +0000 (08:56 +0300)
* mark.c [PARALLEL_MARK] (GC_help_marker): Add assertion that
GC_parallel is true (i.e. GC_markers_m1 is non-zero).
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Set GC_markers_m1 value before starting
the first marker thread (it is already set if fork handling is off).
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_start_mark_threads_inner):
Adjust GC_markers_m1 value only if pthread_create failed.
* win32_threads.c [GC_PTHREADS_PARAMARK] (GC_start_mark_threads_inner):
Likewise.

mark.c
pthread_support.c
win32_threads.c

diff --git a/mark.c b/mark.c
index ecbf1cb..b536802 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1248,8 +1248,7 @@ GC_INNER void GC_help_marker(word my_mark_no)
     mse local_mark_stack[LOCAL_MARK_STACK_SIZE];
                 /* Note: local_mark_stack is quite big (up to 128 KiB). */
 
-    if (!GC_parallel) return;
-
+    GC_ASSERT(GC_parallel);
     GC_acquire_mark_lock();
     while (GC_mark_no < my_mark_no
            || (!GC_help_wanted && GC_mark_no == my_mark_no)) {
index 92565fb..77e051c 100644 (file)
@@ -449,16 +449,20 @@ GC_INNER void GC_start_mark_threads_inner(void)
       }
 #   endif /* !NO_MARKER_SPECIAL_SIGMASK */
 
+#   ifdef CAN_HANDLE_FORK
+      /* To have proper GC_parallel value in GC_help_marker.    */
+      GC_markers_m1 = available_markers_m1;
+#   endif
     for (i = 0; i < available_markers_m1; ++i) {
       if (0 != REAL_FUNC(pthread_create)(GC_mark_threads + i, &attr,
                               GC_mark_thread, (void *)(word)i)) {
         WARN("Marker thread creation failed, errno = %" WARN_PRIdPTR "\n",
              errno);
         /* Don't try to create other marker threads.    */
+        GC_markers_m1 = i;
         break;
       }
     }
-    GC_markers_m1 = i;
 
 #   ifndef NO_MARKER_SPECIAL_SIGMASK
       /* Restore previous signal mask.  */
index 126d332..db8cdae 100644 (file)
@@ -1818,16 +1818,20 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
         }
 #     endif /* !NO_MARKER_SPECIAL_SIGMASK */
 
+#     ifdef CAN_HANDLE_FORK
+        /* To have proper GC_parallel value in GC_help_marker.  */
+        GC_markers_m1 = available_markers_m1;
+#     endif
       for (i = 0; i < available_markers_m1; ++i) {
         marker_last_stack_min[i] = ADDR_LIMIT;
         if (0 != pthread_create(&new_thread, &attr,
                                 GC_mark_thread, (void *)(word)i)) {
           WARN("Marker thread creation failed\n", 0);
           /* Don't try to create other marker threads.    */
+          GC_markers_m1 = i;
           break;
         }
       }
-      GC_markers_m1 = i;
 
 #     ifndef NO_MARKER_SPECIAL_SIGMASK
         /* Restore previous signal mask.        */