diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2017-08-02 01:13:37 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2017-08-02 10:32:17 +0300 |
commit | 4601763a7f6e0c9a5feb0e339f271a6585eb8338 (patch) | |
tree | e66d4aab8e375b983363c9bdc3b9176a63f73669 /mark.c | |
parent | 3df57b56ecceaf8d838f67dad12f879b837f8736 (diff) | |
download | bdwgc-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.c | 22 |
1 files changed, 18 insertions, 4 deletions
@@ -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. */ |