< prev index next >
src/share/vm/gc/parallel/gcTaskManager.cpp
Print this page
*** 376,386 ****
// GCTaskManager
//
GCTaskManager::GCTaskManager(uint workers) :
_workers(workers),
_active_workers(0),
! _idle_workers(0) {
initialize();
}
void GCTaskManager::initialize() {
if (TraceGCTaskManager) {
--- 376,387 ----
// GCTaskManager
//
GCTaskManager::GCTaskManager(uint workers) :
_workers(workers),
_active_workers(0),
! _idle_workers(0),
! _wait_helper() {
initialize();
}
void GCTaskManager::initialize() {
if (TraceGCTaskManager) {
*** 393,403 ****
Monitor::_safepoint_check_never);
// The queue for the GCTaskManager must be a CHeapObj.
GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
_queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
_noop_task = NoopGCTask::create_on_c_heap();
- _idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
_resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
{
// Set up worker threads.
// Distribute the workers among the available processors,
// unless we were told not to, or if the os doesn't want to.
--- 394,403 ----
*** 438,449 ****
GCTaskManager::~GCTaskManager() {
assert(busy_workers() == 0, "still have busy workers");
assert(queue()->is_empty(), "still have queued work");
NoopGCTask::destroy(_noop_task);
_noop_task = NULL;
- WaitForBarrierGCTask::destroy(_idle_inactive_task);
- _idle_inactive_task = NULL;
if (_thread != NULL) {
for (uint i = 0; i < workers(); i += 1) {
GCTaskThread::destroy(thread(i));
set_thread(i, NULL);
}
--- 438,447 ----
*** 495,505 ****
// Stop any idle tasks from exiting their IdleGCTask's
// and get the count for additional IdleGCTask's under
// the GCTaskManager's monitor so that the "more_inactive_workers"
// count is correct.
MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
! _idle_inactive_task->set_should_wait(true);
// active_workers are a number being requested. idle_workers
// are the number currently idle. If all the workers are being
// requested to be active but some are already idle, reduce
// the number of active_workers to be consistent with the
// number of idle_workers. The idle_workers are stuck in
--- 493,503 ----
// Stop any idle tasks from exiting their IdleGCTask's
// and get the count for additional IdleGCTask's under
// the GCTaskManager's monitor so that the "more_inactive_workers"
// count is correct.
MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
! _wait_helper.set_should_wait(true);
// active_workers are a number being requested. idle_workers
// are the number currently idle. If all the workers are being
// requested to be active but some are already idle, reduce
// the number of active_workers to be consistent with the
// number of idle_workers. The idle_workers are stuck in
*** 538,548 ****
void GCTaskManager::release_idle_workers() {
{
MutexLockerEx ml(monitor(),
Mutex::_no_safepoint_check_flag);
! _idle_inactive_task->set_should_wait(false);
monitor()->notify_all();
// Release monitor
}
}
--- 536,546 ----
void GCTaskManager::release_idle_workers() {
{
MutexLockerEx ml(monitor(),
Mutex::_no_safepoint_check_flag);
! _wait_helper.set_should_wait(false);
monitor()->notify_all();
// Release monitor
}
}
*** 832,856 ****
"Should only be used with dynamic GC thread");
return result;
}
void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
! WaitForBarrierGCTask* wait_for_task = manager->idle_inactive_task();
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask:::do_it()"
" should_wait: %s",
! p2i(this), wait_for_task->should_wait() ? "true" : "false");
}
MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
if (TraceDynamicGCThreads) {
gclog_or_tty->print_cr("--- idle %d", which);
}
// Increment has to be done when the idle tasks are created.
// manager->increment_idle_workers();
manager->monitor()->notify_all();
! while (wait_for_task->should_wait()) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it()"
" [" INTPTR_FORMAT "] (%s)->wait()",
p2i(this), p2i(manager->monitor()), manager->monitor()->name());
--- 830,854 ----
"Should only be used with dynamic GC thread");
return result;
}
void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
! WaitHelper* wait_helper = manager->wait_helper();
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask:::do_it()"
" should_wait: %s",
! p2i(this), wait_helper->should_wait() ? "true" : "false");
}
MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
if (TraceDynamicGCThreads) {
gclog_or_tty->print_cr("--- idle %d", which);
}
// Increment has to be done when the idle tasks are created.
// manager->increment_idle_workers();
manager->monitor()->notify_all();
! while (wait_helper->should_wait()) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it()"
" [" INTPTR_FORMAT "] (%s)->wait()",
p2i(this), p2i(manager->monitor()), manager->monitor()->name());
*** 863,873 ****
}
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it() returns"
" should_wait: %s",
! p2i(this), wait_for_task->should_wait() ? "true" : "false");
}
// Release monitor().
}
void IdleGCTask::destroy(IdleGCTask* that) {
--- 861,871 ----
}
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it() returns"
" should_wait: %s",
! p2i(this), wait_helper->should_wait() ? "true" : "false");
}
// Release monitor().
}
void IdleGCTask::destroy(IdleGCTask* that) {
*** 887,952 ****
//
// WaitForBarrierGCTask
//
WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
! WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
return result;
}
! WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
! WaitForBarrierGCTask* result =
! new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
! return result;
! }
!
! WaitForBarrierGCTask::WaitForBarrierGCTask(bool on_c_heap) :
! GCTask(GCTask::Kind::wait_for_barrier_task),
! _is_c_heap_obj(on_c_heap) {
! _monitor = MonitorSupply::reserve();
! set_should_wait(true);
! if (TraceGCTaskManager) {
! tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::WaitForBarrierGCTask()"
! " monitor: " INTPTR_FORMAT,
! p2i(this), p2i(monitor()));
! }
! }
void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
if (that != NULL) {
if (TraceGCTaskManager) {
! tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::destroy()"
! " is_c_heap_obj: %s"
! " monitor: " INTPTR_FORMAT,
! p2i(that),
! that->is_c_heap_obj() ? "true" : "false",
! p2i(that->monitor()));
}
that->destruct();
- if (that->is_c_heap_obj()) {
- FreeHeap(that);
- }
}
}
void WaitForBarrierGCTask::destruct() {
- assert(monitor() != NULL, "monitor should not be NULL");
if (TraceGCTaskManager) {
! tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::destruct()"
! " monitor: " INTPTR_FORMAT,
! p2i(this), p2i(monitor()));
}
this->GCTask::destruct();
// Clean up that should be in the destructor,
// except that ResourceMarks don't call destructors.
! if (monitor() != NULL) {
! MonitorSupply::release(monitor());
! }
! _monitor = (Monitor*) 0xDEAD000F;
}
void WaitForBarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
// Wait for this to be the only busy worker.
assert(manager->monitor()->owned_by_self(), "don't own the lock");
--- 885,917 ----
//
// WaitForBarrierGCTask
//
WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
! WaitForBarrierGCTask* result = new WaitForBarrierGCTask();
return result;
}
! WaitForBarrierGCTask::WaitForBarrierGCTask() : GCTask(GCTask::Kind::wait_for_barrier_task) { }
void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
if (that != NULL) {
if (TraceGCTaskManager) {
! tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destroy()", p2i(that));
}
that->destruct();
}
}
void WaitForBarrierGCTask::destruct() {
if (TraceGCTaskManager) {
! tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destruct()", p2i(this));
}
this->GCTask::destruct();
// Clean up that should be in the destructor,
// except that ResourceMarks don't call destructors.
! _wait_helper.release_monitor();
}
void WaitForBarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
// Wait for this to be the only busy worker.
assert(manager->monitor()->owned_by_self(), "don't own the lock");
*** 961,998 ****
}
void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::do_it() waiting for idle"
! " monitor: " INTPTR_FORMAT,
! p2i(this), p2i(monitor()));
}
{
// First, wait for the barrier to arrive.
MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
do_it_internal(manager, which);
// Release manager->lock().
}
- {
// Then notify the waiter.
! MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
! set_should_wait(false);
! // Waiter doesn't miss the notify in the wait_for method
! // since it checks the flag after grabbing the monitor.
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::do_it()"
! " [" INTPTR_FORMAT "] (%s)->notify_all()",
! p2i(this), p2i(monitor()), monitor()->name());
! }
! monitor()->notify_all();
! // Release monitor().
}
}
! void WaitForBarrierGCTask::wait_for(bool reset) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" WaitForBarrierGCTask::wait_for()"
" should_wait: %s",
p2i(this), should_wait() ? "true" : "false");
--- 926,968 ----
}
void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitForBarrierGCTask::do_it() waiting for idle",
! p2i(this));
}
{
// First, wait for the barrier to arrive.
MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
do_it_internal(manager, which);
// Release manager->lock().
}
// Then notify the waiter.
! _wait_helper.notify();
! }
!
! WaitHelper::WaitHelper() : _should_wait(true), _monitor(MonitorSupply::reserve()) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
! " WaitHelper::WaitHelper()"
! " monitor: " INTPTR_FORMAT,
! p2i(this), p2i(monitor()));
}
}
! void WaitHelper::release_monitor() {
! assert(_monitor != NULL, "");
! MonitorSupply::release(_monitor);
! _monitor = NULL;
! }
!
! WaitHelper::~WaitHelper() {
! release_monitor();
! }
!
! void WaitHelper::wait_for(bool reset) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" WaitForBarrierGCTask::wait_for()"
" should_wait: %s",
p2i(this), should_wait() ? "true" : "false");
*** 1021,1030 ****
--- 991,1014 ----
}
// Release monitor().
}
}
+ void WaitHelper::notify() {
+ MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
+ set_should_wait(false);
+ // Waiter doesn't miss the notify in the wait_for method
+ // since it checks the flag after grabbing the monitor.
+ if (TraceGCTaskManager) {
+ tty->print_cr("[" INTPTR_FORMAT "]"
+ " WaitForBarrierGCTask::do_it()"
+ " [" INTPTR_FORMAT "] (%s)->notify_all()",
+ p2i(this), p2i(monitor()), monitor()->name());
+ }
+ monitor()->notify_all();
+ }
+
Mutex* MonitorSupply::_lock = NULL;
GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
Monitor* MonitorSupply::reserve() {
Monitor* result = NULL;
< prev index next >