From 51e969ce8077d27fd0492e7220c2838747a3f3a5 Mon Sep 17 00:00:00 2001 From: ivmai Date: Sat, 16 Oct 2010 08:44:59 +0000 Subject: [PATCH] 2010-10-16 Ivan Maidanski * darwin_stop_world.c (DARWIN_SUSPEND_GC_THREADS, DARWIN_QUERY_TASK_THREADS): New macro recognized. * darwin_stop_world.c (GC_query_task_threads): add STATIC; initialize to false; define as macro if DARWIN_SUSPEND_GC_THREADS or DARWIN_QUERY_TASK_THREADS; remove FIXME. * darwin_stop_world.c (GC_use_threads_discovery): New function (for setting GC_query_task_threads value). * darwin_stop_world.c (GC_mach_handler_thread, GC_use_mach_handler_thread, GC_mach_thread, GC_MAX_MACH_THREADS, GC_mach_threads, GC_mach_threads_count, GC_suspend_thread_list, GC_darwin_register_mach_handler_thread): Define only if not DARWIN_SUSPEND_GC_THREADS. * darwin_stop_world.c (GC_stop_world, GC_start_world): Exclude the code for GC_query_task_threads case from compilation unless DARWIN_SUSPEND_GC_THREADS. * os_dep.c (GC_darwin_register_mach_handler_thread): Declared only if Darwin threads and not DARWIN_SUSPEND_GC_THREADS. * os_dep.c (GC_mprotect_thread): Call GC_darwin_register_mach_handler_thread only if THREADS and not DARWIN_SUSPEND_GC_THREADS. * pthread_support.c (marker_mach_threads): Don't define if DARWIN_SUSPEND_GC_THREADS. * pthread_support.c (GC_mark_thread): Don't fill in marker_mach_threads if DARWIN_SUSPEND_GC_THREADS. * include/private/gc_locks.h (GC_need_to_lock): Always declare for THREADS case. --- ChangeLog | 29 +++++++++++++++ darwin_stop_world.c | 75 ++++++++++++++++++++++++++------------ include/private/gc_locks.h | 3 +- os_dep.c | 13 ++++--- pthread_support.c | 4 +- 5 files changed, 92 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b271287..4cb76a03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-10-16 Ivan Maidanski + + * darwin_stop_world.c (DARWIN_SUSPEND_GC_THREADS, + DARWIN_QUERY_TASK_THREADS): New macro recognized. + * darwin_stop_world.c (GC_query_task_threads): add STATIC; + initialize to false; define as macro if DARWIN_SUSPEND_GC_THREADS + or DARWIN_QUERY_TASK_THREADS; remove FIXME. + * darwin_stop_world.c (GC_use_threads_discovery): New function + (for setting GC_query_task_threads value). + * darwin_stop_world.c (GC_mach_handler_thread, + GC_use_mach_handler_thread, GC_mach_thread, GC_MAX_MACH_THREADS, + GC_mach_threads, GC_mach_threads_count, GC_suspend_thread_list, + GC_darwin_register_mach_handler_thread): Define only if not + DARWIN_SUSPEND_GC_THREADS. + * darwin_stop_world.c (GC_stop_world, GC_start_world): Exclude + the code for GC_query_task_threads case from compilation unless + DARWIN_SUSPEND_GC_THREADS. + * os_dep.c (GC_darwin_register_mach_handler_thread): Declared only + if Darwin threads and not DARWIN_SUSPEND_GC_THREADS. + * os_dep.c (GC_mprotect_thread): Call + GC_darwin_register_mach_handler_thread only if THREADS and not + DARWIN_SUSPEND_GC_THREADS. + * pthread_support.c (marker_mach_threads): Don't define if + DARWIN_SUSPEND_GC_THREADS. + * pthread_support.c (GC_mark_thread): Don't fill in + marker_mach_threads if DARWIN_SUSPEND_GC_THREADS. + * include/private/gc_locks.h (GC_need_to_lock): Always declare for + THREADS case. + 2010-10-15 Ivan Maidanski * darwin_stop_world.c (GC_query_task_threads): Don't define to diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 229b98ca..3e14b635 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -87,10 +87,31 @@ GC_INNER ptr_t GC_FindTopOfStack(unsigned long stack_start) #endif /* !DARWIN_DONT_PARSE_STACK */ +#define DARWIN_QUERY_TASK_THREADS 1 /* FIXME: Remove this. */ + /* GC_query_task_threads controls whether to obtain the list of */ /* the threads from the kernel or to use GC_threads table. */ - /* FIXME: use STATIC; initialize to false, add setter function. */ - GC_bool GC_query_task_threads = FALSE; +#ifdef DARWIN_SUSPEND_GC_THREADS +# define GC_query_task_threads FALSE +#elif defined(DARWIN_QUERY_TASK_THREADS) +# define GC_query_task_threads TRUE +#else + STATIC GC_bool GC_query_task_threads = FALSE; +#endif /* !DARWIN_SUSPEND_GC_THREADS */ + +/* FIXME: add GC_API and declare in gc.h; add comment; document macros */ +void GC_CALL GC_use_threads_discovery(void) +{ +# if defined(DARWIN_SUSPEND_GC_THREADS) || defined(DARWIN_DONT_PARSE_STACK) + ABORT("Darwin task-threads-based stop and push unsupported"); +# else + GC_ASSERT(!GC_need_to_lock); +# ifndef DARWIN_QUERY_TASK_THREADS + GC_query_task_threads = TRUE; +# endif + GC_init_parallel(); /* just to be consistent with Win32 one */ +# endif +} /* Evaluates the stack range for a given thread. Returns the lower */ /* bound and sets *phi to the upper one. */ @@ -278,7 +299,7 @@ GC_INNER void GC_push_all_stacks(void) vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); } else -# endif +# endif /* !DARWIN_DONT_PARSE_STACK */ /* else */ { for (i = 0; i < (int)listcount; i++) { GC_thread p; @@ -305,25 +326,33 @@ GC_INNER void GC_push_all_stacks(void) GC_total_stacksize = total_size; } -STATIC mach_port_t GC_mach_handler_thread = 0; -STATIC GC_bool GC_use_mach_handler_thread = FALSE; +#ifndef DARWIN_SUSPEND_GC_THREADS -#ifndef GC_MAX_MACH_THREADS -# define GC_MAX_MACH_THREADS THREAD_TABLE_SZ -#endif + STATIC mach_port_t GC_mach_handler_thread = 0; + STATIC GC_bool GC_use_mach_handler_thread = FALSE; + + GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread) + { + GC_mach_handler_thread = thread; + GC_use_mach_handler_thread = TRUE; + } -struct GC_mach_thread { - thread_act_t thread; - GC_bool already_suspended; -}; +# ifndef GC_MAX_MACH_THREADS +# define GC_MAX_MACH_THREADS THREAD_TABLE_SZ +# endif + + struct GC_mach_thread { + thread_act_t thread; + GC_bool already_suspended; + }; -struct GC_mach_thread GC_mach_threads[GC_MAX_MACH_THREADS]; -STATIC int GC_mach_threads_count = 0; -/* FIXME: it is better to implement GC_mach_threads as a hash set. */ + struct GC_mach_thread GC_mach_threads[GC_MAX_MACH_THREADS]; + STATIC int GC_mach_threads_count = 0; + /* FIXME: it is better to implement GC_mach_threads as a hash set. */ -#ifdef PARALLEL_MARK +# ifdef PARALLEL_MARK GC_INNER GC_bool GC_is_mach_marker(thread_act_t thread); -#endif +# endif /* returns true if there's a thread in act_list that wasn't in old_list */ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count, @@ -424,6 +453,8 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count, return changed; } +#endif /* !DARWIN_SUSPEND_GC_THREADS */ + #ifdef MPROTECT_VDB GC_INNER void GC_mprotect_stop(void); GC_INNER void GC_mprotect_resume(void); @@ -459,6 +490,7 @@ GC_INNER void GC_stop_world(void) # endif /* PARALLEL_MARK */ if (GC_query_task_threads) { +# ifndef DARWIN_SUSPEND_GC_THREADS GC_bool changed; thread_act_array_t act_list, prev_list; mach_msg_type_number_t listcount, prevcount; @@ -498,6 +530,7 @@ GC_INNER void GC_stop_world(void) mach_port_deallocate(my_task, prev_list[i]); vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); +# endif /* !DARWIN_SUSPEND_GC_THREADS */ } else { for (i = 0; i < THREAD_TABLE_SZ; i++) { @@ -568,6 +601,7 @@ GC_INNER void GC_start_world(void) # endif if (GC_query_task_threads) { +# ifndef DARWIN_SUSPEND_GC_THREADS int j = GC_mach_threads_count; kern_return_t kern_result; thread_act_array_t act_list; @@ -612,6 +646,7 @@ GC_INNER void GC_start_world(void) } vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); +# endif /* !DARWIN_SUSPEND_GC_THREADS */ } else { mach_port_t my_thread = mach_thread_self(); @@ -633,10 +668,4 @@ GC_INNER void GC_start_world(void) # endif } -GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread) -{ - GC_mach_handler_thread = thread; - GC_use_mach_handler_thread = TRUE; -} - #endif /* GC_DARWIN_THREADS */ diff --git a/include/private/gc_locks.h b/include/private/gc_locks.h index fd43a443..dd2838bb 100644 --- a/include/private/gc_locks.h +++ b/include/private/gc_locks.h @@ -180,7 +180,7 @@ GC_EXTERN unsigned long GC_mark_lock_holder; # endif # endif /* GC_PTHREADS with linux_threads.c implementation */ - + GC_EXTERN GC_bool GC_need_to_lock; # else /* !THREADS */ # define LOCK() @@ -195,7 +195,6 @@ # endif /* !THREADS */ #if defined(UNCOND_LOCK) && !defined(LOCK) - GC_EXTERN GC_bool GC_need_to_lock; /* At least two thread running; need to lock. */ # define LOCK() if (GC_need_to_lock) { UNCOND_LOCK(); } # define UNLOCK() if (GC_need_to_lock) { UNCOND_UNLOCK(); } diff --git a/os_dep.c b/os_dep.c index d8226386..6bbba1b7 100644 --- a/os_dep.c +++ b/os_dep.c @@ -3886,13 +3886,15 @@ GC_INNER void GC_mprotect_resume(void) GC_mprotect_thread_notify(ID_RESUME); } +# ifndef DARWIN_SUSPEND_GC_THREADS + GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread); +# endif + #else /* !THREADS */ /* The compiler should optimize away any GC_mprotect_state computations */ -#define GC_mprotect_state GC_MP_NORMAL +# define GC_mprotect_state GC_MP_NORMAL #endif -GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread); - STATIC void *GC_mprotect_thread(void *arg) { mach_msg_return_t r; @@ -3908,10 +3910,11 @@ STATIC void *GC_mprotect_thread(void *arg) mach_msg_body_t msgh_body; char data[1024]; } msg; - mach_msg_id_t id; - GC_darwin_register_mach_handler_thread(mach_thread_self()); +# if defined(THREADS) && !defined(DARWIN_SUSPEND_GC_THREADS) + GC_darwin_register_mach_handler_thread(mach_thread_self()); +# endif for(;;) { r = mach_msg(&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE | diff --git a/pthread_support.c b/pthread_support.c index 5ceffb9b..beb7e41f 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -321,7 +321,7 @@ static ptr_t marker_sp[MAX_MARKERS - 1] = {0}; static ptr_t marker_bsp[MAX_MARKERS - 1] = {0}; #endif -#ifdef GC_DARWIN_THREADS +#if defined(GC_DARWIN_THREADS) && !defined(DARWIN_SUSPEND_GC_THREADS) static mach_port_t marker_mach_threads[MAX_MARKERS - 1] = {0}; /* Used only by GC_suspend_thread_list(). */ @@ -348,7 +348,7 @@ STATIC void * GC_mark_thread(void * id) # ifdef IA64 marker_bsp[(word)id] = GC_save_regs_in_stack(); # endif -# ifdef GC_DARWIN_THREADS +# if defined(GC_DARWIN_THREADS) && !defined(DARWIN_SUSPEND_GC_THREADS) marker_mach_threads[(word)id] = mach_thread_self(); # endif -- 2.40.0