]> granicus.if.org Git - gc/commitdiff
Fix gctest failure if PARALLEL_MARK (musl)
authorPeter Wang <novalazy@gmail.com>
Thu, 22 Jun 2017 21:25:41 +0000 (00:25 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 4 Jul 2017 21:44:56 +0000 (00:44 +0300)
(Cherry-pick commit 6562982 from 'release-7_6' branch.)

Issue #159 (bdwgc).

The default stack size of threads in musl is not large enough for
GC with parallel markers enabled.  This commit increases the stack
of the created threads to the required minimum.

* include/private/gcconfig.h [PARALLEL_MARK && (HPUX
|| GC_DGUX386_THREADS || NO_GETCONTEXT)] (DEFAULT_STACK_MAYBE_SMALL):
New macro; add TODO item.
* include/private/gcconfig.h [PARALLEL_MARK || THREADS] (MIN_STACK_SIZE):
New macro.
* pthread_support.c (MIN_STACK_SIZE): Do not define.
* pthread_support.c (GC_start_mark_threads_inner): Check
DEFAULT_STACK_MAYBE_SMALL macro instead of HPUX or GC_DGUX386_THREADS.
* pthread_support.c [DEFAULT_STACK_MAYBE_SMALL]
(GC_start_mark_threads_inner): Do not set stack size if old_size is 0.
* pthread_support.c [GC_ASSERTIONS] (WRAP_FUNC(pthread_create)): Use
MIN_STACK_SIZE in GC_ASSERT.
* tests/test.c [GC_PTHREADS && DEFAULT_STACK_MAYBE_SMALL]
(fork_a_thread): Set stack size of the created thread to MIN_STACK_SIZE.
* tests/test.c [GC_PTHREADS] (main): Set size of the created thread
also if DEFAULT_STACK_MAYBE_SMALL is defined.

include/private/gcconfig.h
pthread_support.c
tests/test.c

index 9002f95291ac5811aeec36b090cb570ee4c5c7af..a86c28c1940d0d085db355587b064abfcc2b7576 100644 (file)
 # error "invalid config - PARALLEL_MARK requires GC_THREADS"
 #endif
 
+#if defined(PARALLEL_MARK) && !defined(DEFAULT_STACK_MAYBE_SMALL) \
+    && (defined(HPUX) || defined(GC_DGUX386_THREADS) \
+        || defined(NO_GETCONTEXT) /* e.g. musl */)
+    /* TODO: Test default stack size in configure. */
+# define DEFAULT_STACK_MAYBE_SMALL
+#endif
+
+#ifdef PARALLEL_MARK
+# define MIN_STACK_SIZE (8 * HBLKSIZE * sizeof(word))
+#elif defined(THREADS)
+# define MIN_STACK_SIZE 65536
+#endif
+
 #if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE) \
     && !defined(PLATFORM_ANDROID)
   /* Make the code cancellation-safe.  This basically means that we     */
index 4009a572e3a379dc6e1bfd8f18b88abdd3625d22..6d66792e0f2906bbff1f0d84603cb287832169ac 100644 (file)
@@ -407,22 +407,21 @@ start_mark_threads(void)
     if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
         ABORT("pthread_attr_setdetachstate failed");
 
-#   if defined(HPUX) || defined(GC_DGUX386_THREADS)
-      /* Default stack size is usually too small: fix it. */
-      /* Otherwise marker threads or GC may run out of    */
-      /* space.                                           */
-#     define MIN_STACK_SIZE (8*HBLKSIZE*sizeof(word))
+#   ifdef DEFAULT_STACK_MAYBE_SMALL
+      /* Default stack size is usually too small: increase it.  */
+      /* Otherwise marker threads or GC may run out of space.   */
       {
         size_t old_size;
 
         if (pthread_attr_getstacksize(&attr, &old_size) != 0)
           ABORT("pthread_attr_getstacksize failed");
-        if (old_size < MIN_STACK_SIZE) {
+        if (old_size < MIN_STACK_SIZE
+            && old_size != 0 /* stack size is known */) {
           if (pthread_attr_setstacksize(&attr, MIN_STACK_SIZE) != 0)
             ABORT("pthread_attr_setstacksize failed");
         }
       }
-#   endif /* HPUX || GC_DGUX386_THREADS */
+#   endif /* DEFAULT_STACK_MAYBE_SMALL */
     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)) {
@@ -1715,13 +1714,7 @@ GC_API int WRAP_FUNC(pthread_create)(pthread_t *new_thread,
 #           endif
             stack_size = 1000000;
         }
-#       ifdef PARALLEL_MARK
-          GC_ASSERT(stack_size >= (8*HBLKSIZE*sizeof(word)));
-#       else
-          /* FreeBSD-5.3/Alpha: default pthread stack is 64K,   */
-          /* HBLKSIZE=8192, sizeof(word)=8                      */
-          GC_ASSERT(stack_size >= 65536);
-#       endif
+        GC_ASSERT(stack_size >= MIN_STACK_SIZE);
         /* Our threads may need to do some work for the GC.     */
         /* Ridiculously small threads won't work, and they      */
         /* probably wouldn't work anyway.                       */
index 0c4e9eace760a5be841fb8e8b2810f9ecee4ecb3..7028f1ea8ace590d74b8ecdd2943ad5f5f367f94 100644 (file)
@@ -523,7 +523,26 @@ void check_marks_int_list(sexpr x)
     {
       pthread_t t;
       int code;
-      if ((code = pthread_create(&t, 0, tiny_reverse_test, 0)) != 0) {
+#     ifdef DEFAULT_STACK_MAYBE_SMALL
+        pthread_attr_t attr;
+
+        code = pthread_attr_init(&attr);
+        if (code != 0) {
+          GC_printf("pthread_attr_init failed, error=%d\n", code);
+          FAIL;
+        }
+        code = pthread_attr_setstacksize(&attr, MIN_STACK_SIZE);
+        if (code != 0) {
+          GC_printf("pthread_attr_setstacksize(MIN_STACK_SIZE) failed,"
+                    " error=%d\n", code);
+          FAIL;
+        }
+        code = pthread_create(&t, &attr, tiny_reverse_test, 0);
+        (void)pthread_attr_destroy(&attr);
+#     else
+        code = pthread_create(&t, NULL, tiny_reverse_test, 0);
+#     endif
+      if (code != 0) {
         GC_printf("Small thread creation failed %d\n", code);
         FAIL;
       }
@@ -1895,7 +1914,7 @@ int main(void)
     }
 #   if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) \
         || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) \
-        || defined(GC_OPENBSD_THREADS)
+        || defined(GC_OPENBSD_THREADS) || defined(DEFAULT_STACK_MAYBE_SMALL)
         if ((code = pthread_attr_setstacksize(&attr, 1000 * 1024)) != 0) {
           GC_printf("pthread_attr_setstacksize failed, error=%d\n", code);
           FAIL;