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