< 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);
*** 177,271 **** _end_semaphore->signal(); } } }; - class MutexGangTaskDispatcher : public GangTaskDispatcher { - AbstractGangTask* _task; - - volatile uint _started; - volatile uint _finished; - volatile uint _num_workers; - - Monitor* _monitor; - - public: - MutexGangTaskDispatcher() : - _task(NULL), - _started(0), - _finished(0), - _num_workers(0), - _monitor(new Monitor(Monitor::leaf, "WorkGang dispatcher lock", false, Monitor::_safepoint_check_never)) { - } - - ~MutexGangTaskDispatcher() { - delete _monitor; - } - - void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, bool add_foreground_work) { - MonitorLocker ml(_monitor, Mutex::_no_safepoint_check_flag); - - _task = task; - _num_workers = num_workers; - - // Tell the workers to get to work. - _monitor->notify_all(); - - run_foreground_task_if_needed(task, num_workers, add_foreground_work); - - // Wait for them to finish. - while (_finished < _num_workers) { - ml.wait(); - } - - _task = NULL; - _num_workers = 0; - _started = 0; - _finished = 0; - } - - WorkData worker_wait_for_task() { - MonitorLocker ml(_monitor, Mutex::_no_safepoint_check_flag); - - while (_num_workers == 0 || _started == _num_workers) { - _monitor->wait(); - } - - _started++; - - // Subtract one to get a zero-indexed worker id. - uint worker_id = _started - 1; - - return WorkData(_task, worker_id); - } - - void worker_done_with_task() { - MonitorLocker ml(_monitor, Mutex::_no_safepoint_check_flag); - - _finished++; - - if (_finished == _num_workers) { - // This will wake up all workers and not only the coordinator. - _monitor->notify_all(); - } - } - }; - - static GangTaskDispatcher* create_dispatcher() { - if (UseSemaphoreGCThreadsSynchronization) { - return new SemaphoreGangTaskDispatcher(); - } - - return new MutexGangTaskDispatcher(); - } - 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(create_dispatcher()) { } WorkGang::~WorkGang() { delete _dispatcher; } --- 186,201 ---- _end_semaphore->signal(); } } }; 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 >