--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp Tue Oct 06 14:27:39 2015 -0400
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp Tue Oct 06 18:51:47 2015 +0000
@@ -26,6 +26,7 @@
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/gcTaskThread.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/gcId.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/mutex.hpp"
@@ -48,8 +49,8 @@
case ordinary_task:
result = "ordinary task";
break;
- case barrier_task:
- result = "barrier task";
+ case wait_for_barrier_task:
+ result = "wait for barrier task";
break;
case noop_task:
result = "noop task";
@@ -61,33 +62,24 @@
return result;
};
-GCTask::GCTask() :
- _kind(Kind::ordinary_task),
- _affinity(GCTaskManager::sentinel_worker()){
- initialize();
+GCTask::GCTask() {
+ initialize(Kind::ordinary_task, GCId::current());
}
-GCTask::GCTask(Kind::kind kind) :
- _kind(kind),
- _affinity(GCTaskManager::sentinel_worker()) {
- initialize();
+GCTask::GCTask(Kind::kind kind) {
+ initialize(kind, GCId::current());
}
-GCTask::GCTask(uint affinity) :
- _kind(Kind::ordinary_task),
- _affinity(affinity) {
- initialize();
+GCTask::GCTask(Kind::kind kind, uint gc_id) {
+ initialize(kind, gc_id);
}
-GCTask::GCTask(Kind::kind kind, uint affinity) :
- _kind(kind),
- _affinity(affinity) {
- initialize();
-}
-
-void GCTask::initialize() {
+void GCTask::initialize(Kind::kind kind, uint gc_id) {
+ _kind = kind;
+ _affinity = GCTaskManager::sentinel_worker();
_older = NULL;
_newer = NULL;
+ _gc_id = gc_id;
}
void GCTask::destruct() {
@@ -378,16 +370,7 @@
GCTaskManager::GCTaskManager(uint workers) :
_workers(workers),
_active_workers(0),
- _idle_workers(0),
- _ndc(NULL) {
- initialize();
-}
-
-GCTaskManager::GCTaskManager(uint workers, NotifyDoneClosure* ndc) :
- _workers(workers),
- _active_workers(0),
- _idle_workers(0),
- _ndc(ndc) {
+ _idle_workers(0) {
initialize();
}
@@ -404,7 +387,6 @@
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.
@@ -437,7 +419,6 @@
}
reset_delivered_tasks();
reset_completed_tasks();
- reset_noop_tasks();
reset_barriers();
reset_emptied_queue();
for (uint s = 0; s < workers(); s += 1) {
@@ -450,8 +431,6 @@
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));
@@ -507,7 +486,7 @@
// 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);
+ _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
@@ -550,7 +529,7 @@
{
MutexLockerEx ml(monitor(),
Mutex::_no_safepoint_check_flag);
- _idle_inactive_task->set_should_wait(false);
+ _wait_helper.set_should_wait(false);
monitor()->notify_all();
// Release monitor
}
@@ -671,7 +650,6 @@
// Just hand back a Noop task,
// in case someone wanted us to release resources, or whatever.
result = noop_task();
- increment_noop_tasks();
}
assert(result != NULL, "shouldn't have null task");
if (TraceGCTaskManager) {
@@ -706,11 +684,6 @@
if (TraceGCTaskManager) {
tty->print_cr(" GCTaskManager::note_completion(%u) done", which);
}
- // Notify client that we are done.
- NotifyDoneClosure* ndc = notify_done_closure();
- if (ndc != NULL) {
- ndc->notify(this);
- }
}
if (TraceGCTaskManager) {
tty->print_cr(" GCTaskManager::note_completion(%u) (%s)->notify_all",
@@ -751,7 +724,7 @@
}
void GCTaskManager::release_all_resources() {
- // If you want this to be done atomically, do it in a BarrierGCTask.
+ // If you want this to be done atomically, do it in a WaitForBarrierGCTask.
for (uint i = 0; i < workers(); i += 1) {
set_resource_flag(i, true);
}
@@ -813,25 +786,22 @@
// NoopGCTask
//
-NoopGCTask* NoopGCTask::create() {
- NoopGCTask* result = new NoopGCTask(false);
- return result;
-}
-
NoopGCTask* NoopGCTask::create_on_c_heap() {
- NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
+ NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask();
return result;
}
void NoopGCTask::destroy(NoopGCTask* that) {
if (that != NULL) {
that->destruct();
- if (that->is_c_heap_obj()) {
- FreeHeap(that);
- }
+ FreeHeap(that);
}
}
+// This task should never be performing GC work that require
+// a valid GC id.
+NoopGCTask::NoopGCTask() : GCTask(GCTask::Kind::noop_task, GCId::undefined()) { }
+
void NoopGCTask::destruct() {
// This has to know it's superclass structure, just like the constructor.
this->GCTask::destruct();
@@ -857,12 +827,12 @@
}
void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
- WaitForBarrierGCTask* wait_for_task = manager->idle_inactive_task();
+ WaitHelper* wait_helper = manager->wait_helper();
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask:::do_it()"
" should_wait: %s",
- p2i(this), wait_for_task->should_wait() ? "true" : "false");
+ p2i(this), wait_helper->should_wait() ? "true" : "false");
}
MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
if (TraceDynamicGCThreads) {
@@ -871,7 +841,7 @@
// 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()) {
+ while (wait_helper->should_wait()) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it()"
@@ -888,7 +858,7 @@
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it() returns"
" should_wait: %s",
- p2i(this), wait_for_task->should_wait() ? "true" : "false");
+ p2i(this), wait_helper->should_wait() ? "true" : "false");
}
// Release monitor().
}
@@ -909,140 +879,52 @@
}
//
-// BarrierGCTask
+// WaitForBarrierGCTask
//
-
-void BarrierGCTask::do_it(GCTaskManager* manager, uint which) {
- // Wait for this to be the only busy worker.
- // ??? I thought of having a StackObj class
- // whose constructor would grab the lock and come to the barrier,
- // and whose destructor would release the lock,
- // but that seems like too much mechanism for two lines of code.
- MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
- do_it_internal(manager, which);
- // Release manager->lock().
+WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
+ WaitForBarrierGCTask* result = new WaitForBarrierGCTask();
+ return result;
}
-void BarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
+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");
assert(manager->is_blocked(), "manager isn't blocked");
while (manager->busy_workers() > 1) {
if (TraceGCTaskManager) {
- tty->print_cr("BarrierGCTask::do_it(%u) waiting on %u workers",
+ tty->print_cr("WaitForBarrierGCTask::do_it(%u) waiting on %u workers",
which, manager->busy_workers());
}
manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
}
}
-void BarrierGCTask::destruct() {
- this->GCTask::destruct();
- // Nothing else to do.
-}
-
-//
-// ReleasingBarrierGCTask
-//
-
-void ReleasingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
- MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
- do_it_internal(manager, which);
- manager->release_all_resources();
- // Release manager->lock().
-}
-
-void ReleasingBarrierGCTask::destruct() {
- this->BarrierGCTask::destruct();
- // Nothing else to do.
-}
-
-//
-// NotifyingBarrierGCTask
-//
-
-void NotifyingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
- MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
- do_it_internal(manager, which);
- NotifyDoneClosure* ndc = notify_done_closure();
- if (ndc != NULL) {
- ndc->notify(manager);
- }
- // Release manager->lock().
-}
-
-void NotifyingBarrierGCTask::destruct() {
- this->BarrierGCTask::destruct();
- // Nothing else to do.
-}
-
-//
-// 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) :
- _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->BarrierGCTask::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(GCTaskManager* manager, uint which) {
if (TraceGCTaskManager) {
tty->print_cr("[" INTPTR_FORMAT "]"
- " WaitForBarrierGCTask::do_it() waiting for idle"
- " monitor: " INTPTR_FORMAT,
- p2i(this), p2i(monitor()));
+ " WaitForBarrierGCTask::do_it() waiting for idle",
+ p2i(this));
}
{
// First, wait for the barrier to arrive.
@@ -1050,24 +932,30 @@
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().
+ // 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 WaitForBarrierGCTask::wait_for(bool reset) {
+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()"
@@ -1100,6 +988,20 @@
}
}
+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;
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp Tue Oct 06 14:27:39 2015 -0400
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp Tue Oct 06 18:51:47 2015 +0000
@@ -38,12 +38,8 @@
class GCTaskQueue;
class SynchronizedGCTaskQueue;
class GCTaskManager;
-class NotifyDoneClosure;
// Some useful subclasses of GCTask. You can also make up your own.
class NoopGCTask;
-class BarrierGCTask;
-class ReleasingBarrierGCTask;
-class NotifyingBarrierGCTask;
class WaitForBarrierGCTask;
class IdleGCTask;
// A free list of Monitor*'s.
@@ -64,7 +60,7 @@
enum kind {
unknown_task,
ordinary_task,
- barrier_task,
+ wait_for_barrier_task,
noop_task,
idle_task
};
@@ -72,13 +68,16 @@
};
private:
// Instance state.
- const Kind::kind _kind; // For runtime type checking.
- const uint _affinity; // Which worker should run task.
+ Kind::kind _kind; // For runtime type checking.
+ uint _affinity; // Which worker should run task.
GCTask* _newer; // Tasks are on doubly-linked ...
GCTask* _older; // ... lists.
+ uint _gc_id; // GC Id to use for the thread that executes this task
public:
virtual char* name() { return (char *)"task"; }
+ uint gc_id() { return _gc_id; }
+
// Abstract do_it method
virtual void do_it(GCTaskManager* manager, uint which) = 0;
// Accessors
@@ -105,7 +104,7 @@
return kind()==Kind::ordinary_task;
}
bool is_barrier_task() const {
- return kind()==Kind::barrier_task;
+ return kind()==Kind::wait_for_barrier_task;
}
bool is_noop_task() const {
return kind()==Kind::noop_task;
@@ -120,17 +119,14 @@
GCTask();
// A GCTask of a particular kind, usually barrier or noop.
GCTask(Kind::kind kind);
- // An ordinary GCTask with an affinity.
- GCTask(uint affinity);
- // A GCTask of a particular kind, with and affinity.
- GCTask(Kind::kind kind, uint affinity);
+ GCTask(Kind::kind kind, uint gc_id);
// We want a virtual destructor because virtual methods,
// but since ResourceObj's don't have their destructors
// called, we don't have one at all. Instead we have
// this method, which gets called by subclasses to clean up.
virtual void destruct();
// Methods.
- void initialize();
+ void initialize(Kind::kind kind, uint gc_id);
};
// A doubly-linked list of GCTasks.
@@ -276,21 +272,26 @@
~SynchronizedGCTaskQueue();
};
-// This is an abstract base class for getting notifications
-// when a GCTaskManager is done.
-class NotifyDoneClosure : public CHeapObj<mtGC> {
-public:
- // The notification callback method.
- virtual void notify(GCTaskManager* manager) = 0;
-protected:
- // Constructor.
- NotifyDoneClosure() {
- // Nothing to do.
+class WaitHelper VALUE_OBJ_CLASS_SPEC {
+ private:
+ Monitor* _monitor;
+ volatile bool _should_wait;
+ public:
+ WaitHelper();
+ ~WaitHelper();
+ void wait_for(bool reset);
+ void notify();
+ void set_should_wait(bool value) {
+ _should_wait = value;
}
- // Virtual destructor because virtual methods.
- virtual ~NotifyDoneClosure() {
- // Nothing to do.
+
+ Monitor* monitor() const {
+ return _monitor;
}
+ bool should_wait() const {
+ return _should_wait;
+ }
+ void release_monitor();
};
// Dynamic number of GC threads
@@ -365,7 +366,6 @@
friend class IdleGCTask;
private:
// Instance state.
- NotifyDoneClosure* _ndc; // Notify on completion.
const uint _workers; // Number of workers.
Monitor* _monitor; // Notification of changes.
SynchronizedGCTaskQueue* _queue; // Queue of tasks.
@@ -379,17 +379,13 @@
uint _barriers; // Count of barrier tasks.
uint _emptied_queue; // Times we emptied the queue.
NoopGCTask* _noop_task; // The NoopGCTask instance.
- uint _noop_tasks; // Count of noop tasks.
- WaitForBarrierGCTask* _idle_inactive_task;// Task for inactive workers
+ WaitHelper _wait_helper; // Used by inactive worker
volatile uint _idle_workers; // Number of idled workers
public:
// Factory create and destroy methods.
static GCTaskManager* create(uint workers) {
return new GCTaskManager(workers);
}
- static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
- return new GCTaskManager(workers, ndc);
- }
static void destroy(GCTaskManager* that) {
if (that != NULL) {
delete that;
@@ -409,8 +405,8 @@
Monitor * lock() const {
return _monitor;
}
- WaitForBarrierGCTask* idle_inactive_task() {
- return _idle_inactive_task;
+ WaitHelper* wait_helper() {
+ return &_wait_helper;
}
// Methods.
// Add the argument task to be run.
@@ -452,8 +448,6 @@
// Constructors. Clients use factory, but there might be subclasses.
// Create a GCTaskManager with the appropriate number of workers.
GCTaskManager(uint workers);
- // Create a GCTaskManager that calls back when there's no more work.
- GCTaskManager(uint workers, NotifyDoneClosure* ndc);
// Make virtual if necessary.
~GCTaskManager();
// Accessors.
@@ -469,9 +463,6 @@
// Sets the number of threads that will be used in a collection
void set_active_gang();
- NotifyDoneClosure* notify_done_closure() const {
- return _ndc;
- }
SynchronizedGCTaskQueue* queue() const {
return _queue;
}
@@ -540,17 +531,6 @@
void reset_emptied_queue() {
_emptied_queue = 0;
}
- // Count of the number of noop tasks we've handed out,
- // e.g., to handle resource release requests.
- uint noop_tasks() const {
- return _noop_tasks;
- }
- void increment_noop_tasks() {
- _noop_tasks += 1;
- }
- void reset_noop_tasks() {
- _noop_tasks = 0;
- }
void increment_idle_workers() {
_idle_workers++;
}
@@ -575,11 +555,8 @@
// A noop task that does nothing,
// except take us around the GCTaskThread loop.
class NoopGCTask : public GCTask {
-private:
- const bool _is_c_heap_obj; // Is this a CHeapObj?
public:
// Factory create and destroy methods.
- static NoopGCTask* create();
static NoopGCTask* create_on_c_heap();
static void destroy(NoopGCTask* that);
@@ -590,147 +567,39 @@
}
protected:
// Constructor.
- NoopGCTask(bool on_c_heap) :
- GCTask(GCTask::Kind::noop_task),
- _is_c_heap_obj(on_c_heap) {
- // Nothing to do.
- }
- // Destructor-like method.
- void destruct();
- // Accessors.
- bool is_c_heap_obj() const {
- return _is_c_heap_obj;
- }
-};
-
-// A BarrierGCTask blocks other tasks from starting,
-// and waits until it is the only task running.
-class BarrierGCTask : public GCTask {
-public:
- // Factory create and destroy methods.
- static BarrierGCTask* create() {
- return new BarrierGCTask();
- }
- static void destroy(BarrierGCTask* that) {
- if (that != NULL) {
- that->destruct();
- delete that;
- }
- }
- // Methods from GCTask.
- void do_it(GCTaskManager* manager, uint which);
-protected:
- // Constructor. Clients use factory, but there might be subclasses.
- BarrierGCTask() :
- GCTask(GCTask::Kind::barrier_task) {
- // Nothing to do.
- }
- // Destructor-like method.
- void destruct();
-
- virtual char* name() { return (char *)"barrier task"; }
- // Methods.
- // Wait for this to be the only task running.
- void do_it_internal(GCTaskManager* manager, uint which);
-};
-
-// A ReleasingBarrierGCTask is a BarrierGCTask
-// that tells all the tasks to release their resource areas.
-class ReleasingBarrierGCTask : public BarrierGCTask {
-public:
- // Factory create and destroy methods.
- static ReleasingBarrierGCTask* create() {
- return new ReleasingBarrierGCTask();
- }
- static void destroy(ReleasingBarrierGCTask* that) {
- if (that != NULL) {
- that->destruct();
- delete that;
- }
- }
- // Methods from GCTask.
- void do_it(GCTaskManager* manager, uint which);
-protected:
- // Constructor. Clients use factory, but there might be subclasses.
- ReleasingBarrierGCTask() :
- BarrierGCTask() {
- // Nothing to do.
- }
+ NoopGCTask();
// Destructor-like method.
void destruct();
};
-// A NotifyingBarrierGCTask is a BarrierGCTask
-// that calls a notification method when it is the only task running.
-class NotifyingBarrierGCTask : public BarrierGCTask {
-private:
- // Instance state.
- NotifyDoneClosure* _ndc; // The callback object.
-public:
- // Factory create and destroy methods.
- static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
- return new NotifyingBarrierGCTask(ndc);
- }
- static void destroy(NotifyingBarrierGCTask* that) {
- if (that != NULL) {
- that->destruct();
- delete that;
- }
- }
- // Methods from GCTask.
- void do_it(GCTaskManager* manager, uint which);
-protected:
- // Constructor. Clients use factory, but there might be subclasses.
- NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
- BarrierGCTask(),
- _ndc(ndc) {
- assert(notify_done_closure() != NULL, "can't notify on NULL");
- }
- // Destructor-like method.
- void destruct();
- // Accessor.
- NotifyDoneClosure* notify_done_closure() const { return _ndc; }
-};
-
-// A WaitForBarrierGCTask is a BarrierGCTask
+// A WaitForBarrierGCTask is a GCTask
// with a method you can call to wait until
// the BarrierGCTask is done.
-// This may cover many of the uses of NotifyingBarrierGCTasks.
-class WaitForBarrierGCTask : public BarrierGCTask {
+class WaitForBarrierGCTask : public GCTask {
friend class GCTaskManager;
friend class IdleGCTask;
private:
// Instance state.
- Monitor* _monitor; // Guard and notify changes.
- volatile bool _should_wait; // true=>wait, false=>proceed.
- const bool _is_c_heap_obj; // Was allocated on the heap.
+ WaitHelper _wait_helper;
+ WaitForBarrierGCTask();
public:
virtual char* name() { return (char *) "waitfor-barrier-task"; }
// Factory create and destroy methods.
static WaitForBarrierGCTask* create();
- static WaitForBarrierGCTask* create_on_c_heap();
static void destroy(WaitForBarrierGCTask* that);
// Methods.
void do_it(GCTaskManager* manager, uint which);
- void wait_for(bool reset);
- void set_should_wait(bool value) {
- _should_wait = value;
- }
protected:
- // Constructor. Clients use factory, but there might be subclasses.
- WaitForBarrierGCTask(bool on_c_heap);
// Destructor-like method.
void destruct();
- // Accessors.
- Monitor* monitor() const {
- return _monitor;
- }
- bool should_wait() const {
- return _should_wait;
- }
- bool is_c_heap_obj() {
- return _is_c_heap_obj;
+
+ // Methods.
+ // Wait for this to be the only task running.
+ void do_it_internal(GCTaskManager* manager, uint which);
+
+ void wait_for(bool reset) {
+ _wait_helper.wait_for(reset);
}
};