From 65629822c97dd114c8420d60e0e113e5c37004b5 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Fri, 23 Jun 2017 00:25:41 +0300 Subject: [PATCH] Fix gctest failure if PARALLEL_MARK (musl) 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 | 13 +++++++++++++ pthread_support.c | 21 +++++++-------------- tests/test.c | 23 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 00f4713a..24bd0fb6 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -3000,6 +3000,19 @@ # 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 */ diff --git a/pthread_support.c b/pthread_support.c index 01db651b..a5cad831 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -410,22 +410,21 @@ GC_INNER void GC_start_mark_threads_inner(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 */ # ifndef NO_MARKER_SPECIAL_SIGMASK /* Apply special signal mask to GC marker threads, and don't drop */ @@ -1789,13 +1788,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. */ diff --git a/tests/test.c b/tests/test.c index f650b800..7fc3c092 100644 --- a/tests/test.c +++ b/tests/test.c @@ -537,7 +537,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; } @@ -2179,7 +2198,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; -- 2.40.0