summaryrefslogtreecommitdiff
path: root/darwin_stop_world.c
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2012-05-22 01:02:05 +0200
committerIvan Maidanski <ivmai@mail.ru>2015-07-24 21:50:57 +0300
commit4ceae609d3e20822d7818cdef732348053227e1a (patch)
treed47f09efd0a8e88eb33d768cc7fce2aa8b3e26cb /darwin_stop_world.c
parent61ec29ee41052c7947c7d1c6269aadefcf56d4c9 (diff)
downloadbdwgc-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.c44
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;