< prev index next >

src/hotspot/share/gc/shared/owstTaskTerminator.hpp

Print this page
rev 57895 : [mq]: 8215297-remove-ptt
rev 57896 : imported patch 8215297-some-cleanup

@@ -1,7 +1,8 @@
 /*
  * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -22,18 +23,24 @@
  *
  */
 #ifndef SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
 #define SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
 
-#include "gc/shared/taskqueue.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/thread.hpp"
 
+// Define this to enable additional tracing probes.
+#undef TRACESPINNING
+
+class TaskQueueSetSuper;
+class TerminatorTerminator;
+
 /*
- * OWST stands for Optimized Work Stealing Threads
+ * Provides a task termination protocol. OWST stands for Optimized Work Stealing Threads
  *
- * This is an enhanced implementation of Google's work stealing
+ * This is an enhanced implementation of Google's work stealing task termination
  * protocol, which is described in the paper:
  * "Wessam Hassanein. 2016. Understanding and improving JVM GC work
  * stealing at the data center scale. In Proceedings of the 2016 ACM
  * SIGPLAN International Symposium on Memory Management (ISMM 2016). ACM,
  * New York, NY, USA, 46-54. DOI: https://doi.org/10.1145/2926697.2926706"

@@ -41,41 +48,74 @@
  * Instead of a dedicated spin-master, our implementation will let spin-master relinquish
  * the role before it goes to sleep/wait, allowing newly arrived threads to compete for the role.
  * The intention of above enhancement is to reduce spin-master's latency on detecting new tasks
  * for stealing and termination condition.
  */
+class OWSTTaskTerminator : public CHeapObj<mtGC> {
+  uint _n_threads;
+  TaskQueueSetSuper* _queue_set;
+
+  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
+  volatile uint _offered_termination;
+  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
+
+#ifdef ASSERT
+  bool peek_in_queue_set();
+#endif
+  void yield();
 
-class OWSTTaskTerminator: public ParallelTaskTerminator {
-private:
   Monitor*    _blocker;
   Thread*     _spin_master;
 
+#ifdef TRACESPINNING
+  static uint _total_yields;
+  static uint _total_spins;
+  static uint _total_peeks;
+#endif
+
+  // If we should exit current termination protocol
+  bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
+
+  size_t tasks_in_queue_set() const;
+
+  // Perform spin-master task.
+  // Return true if termination condition is detected, otherwise return false
+  bool do_spin_master_work(TerminatorTerminator* terminator);
+
+  NONCOPYABLE(OWSTTaskTerminator);
+
 public:
-  OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
-    ParallelTaskTerminator(n_threads, queue_set), _spin_master(NULL) {
-    _blocker = new Monitor(Mutex::leaf, "OWSTTaskTerminator", false, Monitor::_safepoint_check_never);
-  }
+  OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
+  ~OWSTTaskTerminator();
 
-  virtual ~OWSTTaskTerminator() {
-    assert(_spin_master == NULL, "Should have been reset");
-    assert(_blocker != NULL, "Can not be NULL");
-    delete _blocker;
+  // The current thread has no work, and is ready to terminate if everyone
+  // else is.  If returns "true", all threads are terminated.  If returns
+  // "false", available work has been observed in one of the task queues,
+  // so the global task is not complete.
+  bool offer_termination() {
+    return offer_termination(NULL);
   }
 
+  // As above, but it also terminates if the should_exit_termination()
+  // method of the terminator parameter returns true. If terminator is
+  // NULL, then it is ignored.
   bool offer_termination(TerminatorTerminator* terminator);
 
-protected:
-  // If should exit current termination protocol
-  virtual bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
-
-private:
-  size_t tasks_in_queue_set() { return _queue_set->tasks(); }
-
-  /*
-   * Perform spin-master task.
-   * Return true if termination condition is detected, otherwise return false
-   */
-  bool do_spin_master_work(TerminatorTerminator* terminator);
+  // Reset the terminator, so that it may be reused again.
+  // The caller is responsible for ensuring that this is done
+  // in an MT-safe manner, once the previous round of use of
+  // the terminator is finished.
+  void reset_for_reuse();
+  // Same as above but the number of parallel threads is set to the
+  // given number.
+  void reset_for_reuse(uint n_threads);
+
+#ifdef TRACESPINNING
+  static uint total_yields() { return _total_yields; }
+  static uint total_spins() { return _total_spins; }
+  static uint total_peeks() { return _total_peeks; }
+  static void print_termination_counts();
+#endif
 };
 
 
 #endif // SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
< prev index next >