< prev index next >

src/hotspot/share/gc/shared/workgroup.cpp

Print this page

        

@@ -107,11 +107,11 @@
 
 // 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 {
+class GangTaskDispatcher : public CHeapObj<mtGC> {
   // The task currently being dispatched to the GangWorkers.
   AbstractGangTask* _task;
 
   volatile uint _started;
   volatile uint _not_finished;

@@ -120,23 +120,27 @@
   Semaphore* _start_semaphore;
   // Semaphore used to notify the coordinator that all workers are done.
   Semaphore* _end_semaphore;
 
 public:
-  SemaphoreGangTaskDispatcher() :
+  GangTaskDispatcher() :
       _task(NULL),
       _started(0),
       _not_finished(0),
       _start_semaphore(new Semaphore()),
       _end_semaphore(new Semaphore())
 { }
 
-  ~SemaphoreGangTaskDispatcher() {
+  ~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,10 +157,14 @@
     _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,10 +173,11 @@
     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,95 +186,16 @@
       _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())
+    _dispatcher(new GangTaskDispatcher())
 { }
 
 WorkGang::~WorkGang() {
   delete _dispatcher;
 }
< prev index next >