< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page
rev 13053 : 8180932: Parallelize safepoint cleanup
Summary: Provide infrastructure to do safepoint cleanup tasks using parallel worker threads
Reviewed-by: dholmes, rehn

@@ -1693,21 +1693,12 @@
   // And in case the vm thread is acquiring a lock during a safepoint
   // See e.g. 6320749
   Thread::muxAcquire(&gListLock, "scavenge - return");
 
   if (MonitorInUseLists) {
-    int inUse = 0;
-    for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
-      nInCirculation+= cur->omInUseCount;
-      int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
-      cur->omInUseCount-= deflated_count;
-      if (ObjectMonitor::Knob_VerifyInUse) {
-        verifyInUse(cur);
-      }
-      nScavenged += deflated_count;
-      nInuse += cur->omInUseCount;
-    }
+    // Note: the thread-local monitors lists get deflated in
+    // a separate pass. See deflate_thread_local_monitors().
 
     // For moribund threads, scan gOmInUseList
     if (gOmInUseList) {
       nInCirculation += gOmInUseCount;
       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);

@@ -1778,10 +1769,37 @@
   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
   GVars.stwRandom = os::random();
   GVars.stwCycle++;
 }
 
+void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+  if (! MonitorInUseLists) return;
+
+  ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
+  ObjectMonitor * freeTailp = NULL;
+
+  int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
+  thread->omInUseCount-= deflated_count;
+  if (ObjectMonitor::Knob_VerifyInUse) {
+    verifyInUse(thread);
+  }
+
+  // Move the scavenged monitors back to the global free list.
+  if (freeHeadp != NULL) {
+    Thread::muxAcquire(&gListLock, "scavenge - return");
+    guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
+    assert(freeTailp->FreeNext == NULL, "invariant");
+
+    gMonitorFreeCount += deflated_count;
+    // constant-time list splice - prepend scavenged segment to gFreeList
+    freeTailp->FreeNext = gFreeList;
+    gFreeList = freeHeadp;
+    Thread::muxRelease(&gListLock);
+  }
+}
+
 // Monitor cleanup on JavaThread::exit
 
 // Iterate through monitor cache and attempt to release thread's monitors
 // Gives up on a particular monitor if an exception occurs, but continues
 // the overall iteration, swallowing the exception.
< prev index next >