summaryrefslogtreecommitdiff
path: root/darwin_stop_world.c
diff options
context:
space:
mode:
authorivmai <ivmai>2010-10-06 20:09:27 +0000
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 21:06:55 +0400
commit24b29a7e89dc3b25b4d6933b7aaf49acf19c71a4 (patch)
tree5c6184fca0e66fa8379c77696667275b66653f63 /darwin_stop_world.c
parent34867e9d2269c71f9753f7ce472904f9c4528a28 (diff)
downloadbdwgc-24b29a7e89dc3b25b4d6933b7aaf49acf19c71a4.tar.gz
2010-10-06 Ivan Maidanski <ivmai@mail.ru>
* darwin_stop_world.c (FindTopOfStack): Change return type to ptr_t (from long); make GC_INNER; add GC_ prefix. * darwin_stop_world.c (GC_push_all_stacks): Add thread_blocked local variable (initialized from the corresponding GC_thread field unless GC_query_task_threads); add assertion that our thread is not blocked; prefix FindTopOfStack with GC_ and remove no longer needed cast to ptr_t of the result; handle thread blocked case (and remove FIXME); use GC_push_all_stack_sections unless GC_query_task_threads (and remove FIXME). * pthread_support.c (GC_FindTopOfStack): Declare (if needed). * pthread_support.c (GC_do_blocking_inner): Call GC_save_regs_in_stack (if needed) before acquiring the lock. * win32_threads.c (GC_do_blocking_inner): Ditto. * pthread_support.c (GC_do_blocking_inner): Set/clear topOfStack field of GC_thread (Darwin only). * include/private/pthread_support.h (GC_thread): Add topOfStack field for Darwin (unless DARWIN_DONT_PARSE_STACK).
Diffstat (limited to 'darwin_stop_world.c')
-rw-r--r--darwin_stop_world.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/darwin_stop_world.c b/darwin_stop_world.c
index 3874d37b..533ea76e 100644
--- a/darwin_stop_world.c
+++ b/darwin_stop_world.c
@@ -49,9 +49,9 @@ typedef struct StackFrame {
unsigned long savedRTOC;
} StackFrame;
-static unsigned long FindTopOfStack(unsigned long stack_start)
+GC_INNER ptr_t GC_FindTopOfStack(unsigned long stack_start)
{
- StackFrame *frame;
+ StackFrame *frame;
if (stack_start == 0) {
# ifdef POWERPC
@@ -82,7 +82,7 @@ static unsigned long FindTopOfStack(unsigned long stack_start)
# ifdef DEBUG_THREADS
/* GC_printf("FindTopOfStack finish at sp = %p\n", frame); */
# endif
- return (unsigned long)frame;
+ return (ptr_t)frame;
}
#endif /* !DARWIN_DONT_PARSE_STACK */
@@ -122,28 +122,36 @@ GC_INNER void GC_push_all_stacks(void)
}
for (i = 0; i < (int)listcount; i++) {
- GC_thread p = GC_query_task_threads ? 0 : GC_threads[i];
+ GC_thread p = GC_query_task_threads ? NULL : GC_threads[i];
for (;; p = p->next) {
thread_act_t thread;
+ GC_bool thread_blocked;
if (GC_query_task_threads) {
thread = act_list[i];
+ thread_blocked = FALSE;
} else {
- if (p == 0) break;
+ if (p == NULL) break;
if (p->flags & FINISHED) continue;
thread = p->stop_info.mach_thread;
+ thread_blocked = (GC_bool)p->thread_blocked;
}
nthreads++;
if (thread == me) {
- /* FIXME: check thread not blocked */
+ GC_ASSERT(!thread_blocked);
lo = GC_approx_sp();
# ifndef DARWIN_DONT_PARSE_STACK
- hi = (ptr_t)FindTopOfStack(0);
+ hi = GC_FindTopOfStack(0);
# endif
found_me = TRUE;
- } else {
- /* FIXME: if blocked then use stop_info.stack_ptr for lo */
+ } else if (thread_blocked) {
+ lo = p->stop_info.stack_ptr;
+# ifndef DARWIN_DONT_PARSE_STACK
+ hi = p->topOfStack;
+# endif
+
+ } else {
/* MACHINE_THREAD_STATE_COUNT does not seem to be defined */
/* everywhere. Hence we use our own version. Alternatively, */
/* we could use THREAD_STATE_MAX (but seems to be not optimal). */
@@ -162,7 +170,7 @@ GC_INNER void GC_push_all_stacks(void)
# if defined(I386)
lo = (void *)state.THREAD_FLD(esp);
# ifndef DARWIN_DONT_PARSE_STACK
- hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(esp));
+ hi = GC_FindTopOfStack(state.THREAD_FLD(esp));
# endif
GC_push_one(state.THREAD_FLD(eax));
GC_push_one(state.THREAD_FLD(ebx));
@@ -175,7 +183,7 @@ GC_INNER void GC_push_all_stacks(void)
# elif defined(X86_64)
lo = (void *)state.THREAD_FLD(rsp);
# ifndef DARWIN_DONT_PARSE_STACK
- hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(rsp));
+ hi = GC_FindTopOfStack(state.THREAD_FLD(rsp));
# endif
GC_push_one(state.THREAD_FLD(rax));
GC_push_one(state.THREAD_FLD(rbx));
@@ -197,7 +205,7 @@ GC_INNER void GC_push_all_stacks(void)
# elif defined(POWERPC)
lo = (void *)(state.THREAD_FLD(r1) - PPC_RED_ZONE_SIZE);
# ifndef DARWIN_DONT_PARSE_STACK
- hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(r1));
+ hi = GC_FindTopOfStack(state.THREAD_FLD(r1));
# endif
GC_push_one(state.THREAD_FLD(r0));
GC_push_one(state.THREAD_FLD(r2));
@@ -234,7 +242,7 @@ GC_INNER void GC_push_all_stacks(void)
# elif defined(ARM32)
lo = (void *)state.__sp;
# ifndef DARWIN_DONT_PARSE_STACK
- hi = (ptr_t)FindTopOfStack(state.__sp);
+ hi = GC_FindTopOfStack(state.__sp);
# endif
GC_push_one(state.__r[0]);
GC_push_one(state.__r[1]);
@@ -258,20 +266,22 @@ GC_INNER void GC_push_all_stacks(void)
# error FIXME for non-x86 || ppc || arm architectures
# endif
} /* thread != me */
+
# ifdef DARWIN_DONT_PARSE_STACK
+ /* p is non-NULL since GC_query_task_threads is FALSE */
hi = (p->flags & MAIN_THREAD) != 0 ? GC_stackbottom : p->stack_end;
# endif
# ifdef DEBUG_THREADS
GC_printf("Darwin: Stack for thread 0x%lx = [%p,%p)\n",
(unsigned long) thread, lo, hi);
# endif
- /* FIXME: use GC_push_all_stack_sections */
- GC_push_all_stack(lo, hi);
total_size += hi - lo; /* lo <= hi */
if (GC_query_task_threads) {
+ GC_push_all_stack(lo, hi);
mach_port_deallocate(my_task, thread);
break;
}
+ GC_push_all_stack_sections(lo, hi, p->traced_stack_sect);
} /* for (p) */
} /* for (i=0; ...) */