2975N/A * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A " GCTaskQueue::GCTaskQueue() constructor",
0N/A " GCTaskQueue::destroy()" 0N/A " is_c_heap_obj: %s",
0N/A // That instance may have been allocated as a CHeapObj, 0N/A // in which case we have to free it explicitly. 0N/A " GCTaskQueue::enqueue(task: " 0N/A// Enqueue a whole list of tasks. Empties the argument list. 0N/A " GCTaskQueue::enqueue(list: " 0N/A // Enqueuing the empty list: nothing to do. 0N/A // Enqueuing to empty list: just acquire elements. 0N/A // Prepend argument list to our queue. 0N/A // empty the argument list. 0N/A " GCTaskQueue::dequeue()",
this);
0N/A// Dequeue one task, preferring one with affinity. 0N/A // Look down to the next barrier for a task with this affinity. 0N/A // Don't consider barrier tasks, nor past them. 0N/A // If we didn't find anything with affinity, just take the next task. 0N/A // Dequeue from remove end. 0N/A // This is slightly more work, and has slightly fewer asserts 0N/A // than removing from the remove end. 2941N/A// Count the elements in the queue and verify the length against 0N/A// SynchronizedGCTaskQueue 0N/A "GCTaskManager monitor",
// name 0N/A // The queue for the GCTaskManager must be a CHeapObj. 0N/A // Set up worker threads. 0N/A // Distribute the workers among the available processors, 0N/A // unless we were told not to, or if the os doesn't want to. 0N/A tty->
print(
"GCTaskManager::initialize: distribution:");
2941N/A "all_workers_active() %d workers %d " 2941N/A "active %d ParallelGCThreads %d ",
2941N/A// Create IdleGCTasks for inactive workers. 2941N/A// Creates tasks in a ResourceArea and assumes 2941N/A// an appropriate ResourceMark. 2941N/A // Stop any idle tasks from exiting their IdleGCTask's 2941N/A // and get the count for additional IdleGCTask's under 2941N/A // the GCTaskManager's monitor so that the "more_inactive_workers" 2941N/A // active_workers are a number being requested. idle_workers 2941N/A // are the number currently idle. If all the workers are being 2941N/A // requested to be active but some are already idle, reduce 2941N/A // the number of active_workers to be consistent with the 2941N/A // number of idle_workers. The idle_workers are stuck in 2941N/A // idle tasks and will no longer be release (since a new GC 2941N/A // is starting). Try later to release enough idle_workers 2941N/A // to allow the desired number of active_workers. 2941N/A "total workers should equal active + inactive");
2941N/A // GCTaskQueue* q was created in a ResourceArea so a 2941N/A // destroy() call is not needed. 0N/A // Notify with the lock held to avoid missed notifies. 0N/A // Release monitor(). 0N/A // Notify with the lock held to avoid missed notifies. 0N/A // Release monitor(). 2941N/A// GC workers wait in get_task() for new work to be added 2941N/A// to the GCTaskManager's queue. When new work is added, 2941N/A// a notify is sent to the waiting GC workers which then 2941N/A// compete to get tasks. If a GC worker wakes up and there 2941N/A// is no work on the queue, it is given a noop_task to execute 2941N/A// and then loops to find more work. 0N/A // Grab the queue lock. 0N/A // Wait while the queue is block or 0N/A // there is nothing to do, except maybe release resources. 0N/A // We've reacquired the queue lock here. 0N/A // Figure out which condition caused us to exit the loop above. 0N/A "blocker shouldn't be bogus");
0N/A // The queue is empty, but we were woken up. 0N/A // Just hand back a Noop task, 0N/A // in case someone wanted us to release resources, or whatever. 0N/A // Release monitor(). 0N/A // If we are blocked, check if the completing thread is the blocker. 0N/A "blocker shouldn't be bogus");
0N/A // Notify client that we are done. 0N/A // Tell everyone that a task has completed. 0N/A // Release monitor(). 0N/A // If you want this to be done atomically, do it in a BarrierGCTask. 0N/A // This can be done without a lock because each thread reads one element. 0N/A // This can be done without a lock because each thread writes one element. 2941N/A// "list" contains tasks that are ready to execute. Those 2941N/A// tasks are added to the GCTaskManager's queue of tasks and 2941N/A// then the GC workers are notified that there is new work to 2941N/A// Typically different types of tasks can be added to the "list". 2941N/A// For example in PSScavenge OldToYoungRootsTask, SerialOldToYoungRootsTask, 2941N/A// ScavengeRootsTask, and StealTask tasks are all added to the list 2941N/A// and then the GC workers are notified of new work. The tasks are 2941N/A// handed out in the order in which they are added to the list 2941N/A// (although execution is not necessarily in that order). As long 2941N/A// as any tasks are running the GCTaskManager will wait for execution 2941N/A// to complete. GC workers that execute a stealing task remain in 2941N/A// the stealing task until all stealing tasks have completed. The load 2941N/A// balancing afforded by the stealing tasks work best if the stealing 2941N/A// tasks are added last to the list. 2975N/A // The barrier task will be read by one of the GC 2975N/A // workers once it is added to the list of tasks. 2975N/A // Be sure that is globally visible before the 2975N/A // GC worker reads it (which is after the task is added 2975N/A // to the list of tasks below). 0N/A // We have to release the barrier tasks! 0N/A // This has to know it's superclass structure, just like the constructor. 0N/A // Nothing else to do. 2975N/A "Should only be used with dynamic GC thread");
2975N/A "Should only be used with dynamic GC thread");
2941N/A // Increment has to be done when the idle tasks are created. 2941N/A // manager->increment_idle_workers(); 2941N/A " IdleGCTask::do_it() returns" 2941N/A // This has to know it's superclass structure, just like the constructor. 0N/A // Wait for this to be the only busy worker. 0N/A // ??? I thought of having a StackObj class 0N/A // whose constructor would grab the lock and come to the barrier, 0N/A // and whose destructor would release the lock, 0N/A // but that seems like too much mechanism for two lines of code. 0N/A // Release manager->lock(). 0N/A // Wait for this to be the only busy worker. 0N/A // Nothing else to do. 0N/A// ReleasingBarrierGCTask 0N/A // Release manager->lock(). 0N/A // Nothing else to do. 0N/A// NotifyingBarrierGCTask 0N/A // Release manager->lock(). 0N/A // Nothing else to do. 0N/A// WaitForBarrierGCTask 0N/A " WaitForBarrierGCTask::WaitForBarrierGCTask()" 0N/A " WaitForBarrierGCTask::destroy()" 0N/A " is_c_heap_obj: %s" 0N/A " WaitForBarrierGCTask::destruct()" 0N/A // Clean up that should be in the destructor, 0N/A // except that ResourceMarks don't call destructors. 0N/A " WaitForBarrierGCTask::do_it() waiting for idle" 0N/A // First, wait for the barrier to arrive. 0N/A // Release manager->lock(). 0N/A // Then notify the waiter. 0N/A // Waiter doesn't miss the notify in the wait_for method 0N/A // since it checks the flag after grabbing the monitor. 0N/A " WaitForBarrierGCTask::do_it()" 0N/A // Release monitor(). 0N/A " WaitForBarrierGCTask::wait_for()" 0N/A // Grab the lock and check again. 0N/A " WaitForBarrierGCTask::wait_for()" 0N/A // Reset the flag in case someone reuses this task. 0N/A " WaitForBarrierGCTask::wait_for() returns" 0N/A // Release monitor(). 0N/A // Lazy initialization: possible race. 0N/A "MonitorSupply mutex",
// name 0N/A // Lazy initialization. 0N/A "MonitorSupply monitor",
// name