< 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 >