(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.
# 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 */
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)) {
# 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. */
{
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;
}
}
# 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;