1 /*
   2  * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 #ifndef SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
  24 #define SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
  25 
  26 #include "gc/shared/taskqueue.hpp"
  27 #include "runtime/mutex.hpp"
  28 #include "runtime/thread.hpp"
  29 
  30 /*
  31  * OWST stands for Optimized Work Stealing Threads
  32  *
  33  * This is an enhanced implementation of Google's work stealing
  34  * protocol, which is described in the paper:
  35  * Understanding and improving JVM GC work stealing at the data center scale
  36  * (http://dl.acm.org/citation.cfm?id=2926706)
  37  *
  38  * Instead of a dedicated spin-master, our implementation will let spin-master to relinquish
  39  * the role before it goes to sleep/wait, so allows newly arrived thread to compete for the role.
  40  * The intention of above enhancement, is to reduce spin-master's latency on detecting new tasks
  41  * for stealing and termination condition.
  42  */
  43 
  44 class OWSTTaskTerminator: public ParallelTaskTerminator {
  45 private:
  46   Monitor*    _blocker;
  47   Thread*     _spin_master;
  48 
  49 public:
  50   OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
  51     ParallelTaskTerminator(n_threads, queue_set), _spin_master(NULL) {
  52     _blocker = new Monitor(Mutex::leaf, "OWSTTaskTerminator", false, Monitor::_safepoint_check_never);
  53   }
  54 
  55   virtual ~OWSTTaskTerminator() {
  56     assert(_blocker != NULL, "Can not be NULL");
  57     delete _blocker;
  58   }
  59 
  60   bool offer_termination(TerminatorTerminator* terminator);
  61 
  62 protected:
  63   // If should exit current termination protocol
  64   virtual bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
  65 
  66 private:
  67   size_t tasks_in_queue_set() { return _queue_set->tasks(); }
  68 
  69   /*
  70    * Perform spin-master task.
  71    * return true if termination condition is detected
  72    * otherwise, return false
  73    */
  74   bool do_spin_master_work(TerminatorTerminator* terminator);
  75 };
  76 
  77 
  78 #endif // SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP