This patch fixes various problems with safepoints. (1) We must increase ->nr_in_safepoint from gc_start(); otherwise we'll deadlock as the tread that called gc_start() will never enter gc_safepoint().
(2) Don't let threads enter gc_start() until we've returned from gc_start() for a previous safepoint. (3) Let only one thread wait in gc_start() when it's called concurrently. Only the first thread will wait and others will be be treated just as if they had entered gc_safepoint(). (4) Fix gc_start() when called during early bootstrap code when no threads are started. With the above fixes, GcTortureTest passes when gc_start() is called from object allocator. Cc: Vegard Nossum <vegard.nos...@gmail.com> Signed-off-by: Pekka Enberg <penb...@cs.helsinki.fi> --- vm/gc.c | 76 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 55 insertions(+), 21 deletions(-) diff --git a/vm/gc.c b/vm/gc.c index 949a6c9..514b50e 100644 --- a/vm/gc.c +++ b/vm/gc.c @@ -20,6 +20,9 @@ static unsigned int nr_in_safepoint = 0; static pthread_cond_t can_continue_cond = PTHREAD_COND_INITIALIZER; static bool can_continue; +static pthread_cond_t can_enter_cond = PTHREAD_COND_INITIALIZER; +static bool can_enter = true; + void gc_init(void) { gc_safepoint_page = alloc_guard_page(false); @@ -53,11 +56,56 @@ static void unhide_safepoint_guard_page(void) unhide_guard_page(gc_safepoint_page); } +static void do_gc_reclaim(void) +{ + /* TODO: Do main GC work here. */ +} + +/* Callers must hold safepoint_mutex */ +static void do_gc_safepoint(void) +{ + /* Only the GC thread will be waiting for this. */ + if (++nr_in_safepoint == nr_threads) + pthread_cond_signal(&everyone_in_cond); + + /* Block until GC has finished */ + while (!can_continue) + pthread_cond_wait(&can_continue_cond, &safepoint_mutex); + + /* Only the GC thread will be waiting for this. */ + if (--nr_in_safepoint == 0) + pthread_cond_signal(&everyone_out_cond); +} + +void gc_safepoint(void) +{ + pthread_mutex_lock(&safepoint_mutex); + + do_gc_safepoint(); + + pthread_mutex_unlock(&safepoint_mutex); +} + void gc_start(void) { pthread_mutex_lock(&safepoint_mutex); - assert(nr_in_safepoint == 0); + /* There are no threads running during early bootstrap. */ + if (nr_threads == 0) { + do_gc_reclaim(); + goto out; + } + + /* Wait for everyone to leave a previous safepoint. */ + while (!can_enter) + pthread_cond_wait(&can_enter_cond, &safepoint_mutex); + + if (nr_in_safepoint != 0) { + do_gc_safepoint(); + goto out; + } + + ++nr_in_safepoint; can_continue = false; hide_safepoint_guard_page(); @@ -68,33 +116,19 @@ void gc_start(void) /* At this point, we know that everyone is in the safepoint. */ unhide_safepoint_guard_page(); - /* TODO: Do main GC work here. */ + do_gc_reclaim(); /* Resume other threads */ + --nr_in_safepoint; can_continue = true; + can_enter = false; pthread_cond_broadcast(&can_continue_cond); while (nr_in_safepoint != 0) pthread_cond_wait(&everyone_out_cond, &safepoint_mutex); - pthread_mutex_unlock(&safepoint_mutex); -} - -void gc_safepoint(void) -{ - pthread_mutex_lock(&safepoint_mutex); - - /* Only the GC thread will be waiting for this. */ - if (++nr_in_safepoint == nr_threads) - pthread_cond_signal(&everyone_in_cond); - - /* Block until GC has finished */ - while (!can_continue) - pthread_cond_wait(&can_continue_cond, &safepoint_mutex); - - /* Only the GC thread will be waiting for this. */ - if (--nr_in_safepoint == 0) - pthread_cond_signal(&everyone_out_cond); - + can_enter = true; + pthread_cond_broadcast(&can_enter_cond); +out: pthread_mutex_unlock(&safepoint_mutex); } -- 1.5.6.3 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel