changeset 2060:b7a938236e43

7014679: G1: deadlock during concurrent cleanup Summary: There's a potential deadlock between the concurrent cleanup thread and the GC workers that are trying to allocate and waiting for more free regions to be made available. Reviewed-by: iveresov, jcoomes
author tonyp
date Mon, 31 Jan 2011 16:28:40 -0500
parents 3582bf76420e
children e49cfa28f585
files src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
diffstat 1 files changed, 8 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Thu Jan 27 16:11:27 2011 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Mon Jan 31 16:28:40 2011 -0500
@@ -251,6 +251,14 @@
 
         // Now do the remainder of the cleanup operation.
         _cm->completeCleanup();
+        // Notify anyone who's waiting that there are no more free
+        // regions coming. We have to do this before we join the STS,
+        // otherwise we might deadlock: a GC worker could be blocked
+        // waiting for the notification whereas this thread will be
+        // blocked for the pause to finish while it's trying to join
+        // the STS, which is conditional on the GC workers finishing.
+        g1h->reset_free_regions_coming();
+
         _sts.join();
         g1_policy->record_concurrent_mark_cleanup_completed();
         _sts.leave();
@@ -262,9 +270,6 @@
           gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]",
                                  cleanup_end_sec - cleanup_start_sec);
         }
-
-        // We're done: no more free regions coming.
-        g1h->reset_free_regions_coming();
       }
       guarantee(cm()->cleanup_list_is_empty(),
                 "at this point there should be no regions on the cleanup list");