]> granicus.if.org Git - gc/commitdiff
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>
Fri, 29 Sep 2017 20:56:06 +0000 (23:56 +0300)
(Cherry-pick commit 46d2a44 from 'release-7_6' branch.)

* 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]
(start_mark_threads): 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]
(start_mark_threads): Likewise.
* pthread_support.c [PARALLEL_MARK] (start_mark_threads):
Adjust GC_markers_m1 value only if pthread_create failed.
* win32_threads.c [GC_PTHREADS_PARAMARK] (start_mark_threads):
Likewise.

mark.c
pthread_support.c
win32_threads.c

diff --git a/mark.c b/mark.c
index e58ed0d2f6014928f7cc63801132717414e7513b..c2268fab53efed02c72b82924cb04ff316f9f0c8 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1204,8 +1204,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 5715f8979388ec5ca4e2b67801c20cc33ef9cffd..67f9575bc1785fc6a1efdebef350f3fc8dfdb1d5 100644 (file)
@@ -422,16 +422,21 @@ start_mark_threads(void)
         }
       }
 #   endif /* DEFAULT_STACK_MAYBE_SMALL */
+
+#   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;
     (void)pthread_attr_destroy(&attr);
     GC_wait_for_markers_init();
     GC_COND_LOG_PRINTF("Started %d mark helper threads\n", GC_markers_m1);
index 8f23f4871741f24194843af48fbd995ca0c486ce..6de84227c4bd25c39fbe91952da172ae3f54df20 100644 (file)
@@ -1768,16 +1768,20 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
       if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
         ABORT("pthread_attr_setdetachstate failed");
 
+#     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;
       (void)pthread_attr_destroy(&attr);
       GC_wait_for_markers_init();
       GC_COND_LOG_PRINTF("Started %d mark helper threads\n", GC_markers_m1);