< prev index next >
src/hotspot/share/gc/shared/workgroup.cpp
Print this page
*** 107,117 ****
// WorkGang dispatcher implemented with semaphores.
//
// Semaphores don't require the worker threads to re-claim the lock when they wake up.
// This helps lowering the latency when starting and stopping the worker threads.
! class SemaphoreGangTaskDispatcher : public GangTaskDispatcher {
// The task currently being dispatched to the GangWorkers.
AbstractGangTask* _task;
volatile uint _started;
volatile uint _not_finished;
--- 107,117 ----
// WorkGang dispatcher implemented with semaphores.
//
// Semaphores don't require the worker threads to re-claim the lock when they wake up.
// This helps lowering the latency when starting and stopping the worker threads.
! class GangTaskDispatcher : public CHeapObj<mtGC> {
// The task currently being dispatched to the GangWorkers.
AbstractGangTask* _task;
volatile uint _started;
volatile uint _not_finished;
*** 120,142 ****
Semaphore* _start_semaphore;
// Semaphore used to notify the coordinator that all workers are done.
Semaphore* _end_semaphore;
public:
! SemaphoreGangTaskDispatcher() :
_task(NULL),
_started(0),
_not_finished(0),
_start_semaphore(new Semaphore()),
_end_semaphore(new Semaphore())
{ }
! ~SemaphoreGangTaskDispatcher() {
delete _start_semaphore;
delete _end_semaphore;
}
void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, bool add_foreground_work) {
// No workers are allowed to read the state variables until they have been signaled.
_task = task;
_not_finished = num_workers;
--- 120,146 ----
Semaphore* _start_semaphore;
// Semaphore used to notify the coordinator that all workers are done.
Semaphore* _end_semaphore;
public:
! GangTaskDispatcher() :
_task(NULL),
_started(0),
_not_finished(0),
_start_semaphore(new Semaphore()),
_end_semaphore(new Semaphore())
{ }
! ~GangTaskDispatcher() {
delete _start_semaphore;
delete _end_semaphore;
}
+ // Coordinator API.
+
+ // Distributes the task out to num_workers workers.
+ // Returns when the task has been completed by all workers.
void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, bool add_foreground_work) {
// No workers are allowed to read the state variables until they have been signaled.
_task = task;
_not_finished = num_workers;
*** 153,162 ****
--- 157,170 ----
_task = NULL;
_started = 0;
}
+ // Worker API.
+
+ // Waits for a task to become available to the worker.
+ // Returns when the worker has been assigned a task.
WorkData worker_wait_for_task() {
// Wait for the coordinator to dispatch a task.
_start_semaphore->wait();
uint num_started = Atomic::add(&_started, 1u);
*** 165,174 ****
--- 173,183 ----
uint worker_id = num_started - 1;
return WorkData(_task, worker_id);
}
+ // Signal to the coordinator that the worker is done with the assigned task.
void worker_done_with_task() {
// Mark that the worker is done with the task.
// The worker is not allowed to read the state variables after this line.
uint not_finished = Atomic::sub(&_not_finished, 1u);
*** 182,192 ****
WorkGang::WorkGang(const char* name,
uint workers,
bool are_GC_task_threads,
bool are_ConcurrentGC_threads) :
AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
! _dispatcher(new SemaphoreGangTaskDispatcher())
{ }
WorkGang::~WorkGang() {
delete _dispatcher;
}
--- 191,201 ----
WorkGang::WorkGang(const char* name,
uint workers,
bool are_GC_task_threads,
bool are_ConcurrentGC_threads) :
AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
! _dispatcher(new GangTaskDispatcher())
{ }
WorkGang::~WorkGang() {
delete _dispatcher;
}
< prev index next >