diff options
author | Zoltan Varga <vargaz@gmail.com> | 2012-05-22 01:02:05 +0200 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2015-07-24 21:50:57 +0300 |
commit | 4ceae609d3e20822d7818cdef732348053227e1a (patch) | |
tree | d47f09efd0a8e88eb33d768cc7fce2aa8b3e26cb /darwin_stop_world.c | |
parent | 61ec29ee41052c7947c7d1c6269aadefcf56d4c9 (diff) | |
download | bdwgc-4ceae609d3e20822d7818cdef732348053227e1a.tar.gz |
Add alt-stack registration support
(Apply commit ff4ec56 from 'mono_libgc' branch.)
Fix altstack support in libgc by registering the bounds of the normal
stack and the altstack with it.
* darwin_stop_world.c (GC_stack_range_for): Add paltstack_lo,
paltstack_hi argments; set *paltstack_lo, *paltstack_hi, adjust lo and
hi if p->altstack set.
* darwin_stop_world.c (GC_push_all_stacks): Declare altstack_lo,
altstack_hi local variables; pass &altstack_lo, &altstack_hi to
GC_stack_range_for; do not call GC_push_all_stack(lo, hi) and
adjust total_size by hi-lo if lo is NULL; call
GC_push_all_stack(altstack_lo, altstack_hi) and increment total_size
by altstack_hi-altstack_lo if altstack_lo is non-NULL.
* include/gc.h (GC_register_altstack): New API function declaration.
* include/private/pthread_support.h (GC_Thread_Rep): Add altstack,
altstack_size, stack, stack_size fields.
* pthread_stop_world.c (GC_push_all_stacks): Adjust hi value if
p->altstack set.
* pthread_support.c (main_pthread_self, main_stack, main_altstack,
main_stack_size, main_altstack_size): New static variables.
* pthread_support.c (GC_register_altstack): New function.
* pthread_support.c (GC_thr_init): Set altstack, altstack_size, stack,
stack_size fields from values saved by GC_register_altstack (if called
before GC_thr_init).
* win32_threads.c (GC_register_altstack): New function (unimplemented).
Diffstat (limited to 'darwin_stop_world.c')
-rw-r--r-- | darwin_stop_world.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 718e2f5c..23979035 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -129,7 +129,8 @@ GC_API void GC_CALL GC_use_threads_discovery(void) /* Evaluates the stack range for a given thread. Returns the lower */ /* bound and sets *phi to the upper one. */ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p, - GC_bool thread_blocked, mach_port_t my_thread) + GC_bool thread_blocked, mach_port_t my_thread, + ptr_t *paltstack_lo, ptr_t *paltstack_hi) { ptr_t lo; if (thread == my_thread) { @@ -302,6 +303,16 @@ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p, /* p is guaranteed to be non-NULL regardless of GC_query_task_threads. */ *phi = (p->flags & MAIN_THREAD) != 0 ? GC_stackbottom : p->stack_end; # endif + + if (p->altstack && lo >= p->altstack && lo <= p->altstack + p->altstack_size) { + *paltstack_lo = lo; + *paltstack_hi = p->altstack + p->altstack_size; + lo = (char*)p->stack; + *phi = (char*)p->stack + p->stack_size; + } else { + *paltstack_lo = NULL; + } + # ifdef DEBUG_THREADS GC_log_printf("Darwin: Stack for thread %p = [%p,%p)\n", (void *)thread, lo, *phi); @@ -312,7 +323,7 @@ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p, GC_INNER void GC_push_all_stacks(void) { int i; - ptr_t lo, hi; + ptr_t lo, hi, altstack_lo, altstack_hi; task_t my_task = current_task(); mach_port_t my_thread = mach_thread_self(); GC_bool found_me = FALSE; @@ -334,10 +345,17 @@ GC_INNER void GC_push_all_stacks(void) for (i = 0; i < (int)listcount; i++) { thread_act_t thread = act_list[i]; - lo = GC_stack_range_for(&hi, thread, NULL, FALSE, my_thread); - GC_ASSERT((word)lo <= (word)hi); - total_size += hi - lo; - GC_push_all_stack(lo, hi); + lo = GC_stack_range_for(&hi, thread, NULL, FALSE, my_thread, + &altstack_lo, &altstack_hi); + if (lo) { + GC_ASSERT((word)lo <= (word)hi); + total_size += hi - lo; + GC_push_all_stack(lo,hi); + } + if (altstack_lo) { + total_size += altstack_hi - altstack_lo; + GC_push_all_stack(altstack_lo,altstack_hi); + } nthreads++; if (thread == my_thread) found_me = TRUE; @@ -355,10 +373,16 @@ GC_INNER void GC_push_all_stacks(void) if ((p->flags & FINISHED) == 0) { thread_act_t thread = (thread_act_t)p->stop_info.mach_thread; lo = GC_stack_range_for(&hi, thread, p, (GC_bool)p->thread_blocked, - my_thread); - GC_ASSERT((word)lo <= (word)hi); - total_size += hi - lo; - GC_push_all_stack_sections(lo, hi, p->traced_stack_sect); + my_thread, &altstack_lo, &altstack_hi); + if (lo) { + GC_ASSERT((word)lo <= (word)hi); + total_size += hi - lo; + GC_push_all_stack_sections(lo, hi, p->traced_stack_sect); + } + if (altstack_lo) { + total_size += altstack_hi - altstack_lo; + GC_push_all_stack(altstack_lo, altstack_hi); + } nthreads++; if (thread == my_thread) found_me = TRUE; |