summaryrefslogtreecommitdiff
path: root/mark.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2017-08-02 01:13:37 +0300
committerIvan Maidanski <ivmai@mail.ru>2017-08-02 10:32:17 +0300
commit4601763a7f6e0c9a5feb0e339f271a6585eb8338 (patch)
treee66d4aab8e375b983363c9bdc3b9176a63f73669 /mark.c
parent3df57b56ecceaf8d838f67dad12f879b837f8736 (diff)
downloadbdwgc-4601763a7f6e0c9a5feb0e339f271a6585eb8338.tar.gz
Use heap-allocated memory for local mark stack of non-marker thread
Issue #159 (bdwgc). The memory is allocated using GET_MEM to avoid to make sure that it is not accidentally scanned by the collector. * include/private/gcconfig.h [!PARALLEL_MARK && THREADS] (MIN_STACK_SIZE): Do not define. * include/private/gcconfig.h [PARALLEL_MARK] (MIN_STACK_SIZE): Add comment. * mark.c [PARALLEL_MARK] (main_local_mark_stack): New static variable. * mark.c [PARALLEL_MARK] (GC_wait_for_markers_init): Declare bytes_to_get local variable; allocate local mark stack (using GET_MEM) and set main_local_mark_stack (if not yet allocated by the parent process). * mark [PARALLEL_MARK] (GC_do_parallel_mark): Remove local_mark_stack huge local variable; use main_local_mark_stack instead of local_mark_stack. * pthread_support.c [GC_ASSERTIONS] (WRAP_FUNC(pthread_create)): Use hard-coded value (65536) instead of MIN_STACK_SIZE in GC_ASSERT. * tests/test.c [GC_PTHREADS && DEFAULT_STACK_MAYBE_SMALL] (fork_a_thread): Do not set stack size for the created threads. * tests/test.c [GC_PTHREADS] (main): Do not check DEFAULT_STACK_MAYBE_SMALL.
Diffstat (limited to 'mark.c')
-rw-r--r--mark.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/mark.c b/mark.c
index 17fb511e..179cfb57 100644
--- a/mark.c
+++ b/mark.c
@@ -929,6 +929,8 @@ STATIC unsigned GC_active_count = 0; /* Number of active helpers. */
GC_INNER word GC_mark_no = 0;
+static mse *main_local_mark_stack;
+
#ifdef LINT2
# define LOCAL_MARK_STACK_SIZE (HBLKSIZE / 8)
#else
@@ -947,6 +949,21 @@ GC_INNER void GC_wait_for_markers_init(void)
if (GC_markers_m1 == 0)
return;
+ /* Allocate the local mark stack for the thread that holds GC lock. */
+# ifndef CAN_HANDLE_FORK
+ GC_ASSERT(NULL == main_local_mark_stack);
+# else
+ if (NULL == main_local_mark_stack)
+# endif
+ {
+ size_t bytes_to_get =
+ ROUNDUP_PAGESIZE_IF_MMAP(LOCAL_MARK_STACK_SIZE * sizeof(mse));
+ main_local_mark_stack = (mse *)GET_MEM(bytes_to_get);
+ if (NULL == main_local_mark_stack)
+ ABORT("Insufficient memory for main local_mark_stack");
+ GC_add_to_our_memory((ptr_t)main_local_mark_stack, bytes_to_get);
+ }
+
/* Reuse marker lock and builders count to synchronize */
/* marker threads startup. */
GC_acquire_mark_lock();
@@ -1188,9 +1205,6 @@ STATIC void GC_mark_local(mse *local_mark_stack, int id)
/* empty. */
STATIC void GC_do_parallel_mark(void)
{
- mse local_mark_stack[LOCAL_MARK_STACK_SIZE];
- /* Note: local_mark_stack is quite big (up to 128 KiB). */
-
GC_acquire_mark_lock();
GC_ASSERT(I_HOLD_LOCK());
/* This could be a GC_ASSERT, but it seems safer to keep it on */
@@ -1206,7 +1220,7 @@ STATIC void GC_do_parallel_mark(void)
GC_release_mark_lock();
GC_notify_all_marker();
/* Wake up potential helpers. */
- GC_mark_local(local_mark_stack, 0);
+ GC_mark_local(main_local_mark_stack, 0);
GC_acquire_mark_lock();
GC_help_wanted = FALSE;
/* Done; clean up. */