--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCPhaseManager.hpp Thu Apr 13 16:38:39 2017 -0400
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_CONCURRENTGCPHASEMANAGER_HPP
+#define SHARE_VM_GC_CONCURRENTGCPHASEMANAGER_HPP
+
+#include "memory/allocation.hpp"
+
+// Manage concurrent phase information, to support WhiteBox testing.
+// Managers are stack allocated. Managers may be nested, to support
+// nested subphases.
+class ConcurrentGCPhaseManager : public StackObj {
+public:
+
+ // Special phase ids used by all GC's that use this facility.
+ static const int UNCONSTRAINED_PHASE = 0; // Unconstrained or no request.
+ static const int IDLE_PHASE = 1; // Concurrent processing is idle.
+
+ // Stack of phase managers.
+ class Stack VALUE_OBJ_CLASS_SPEC {
+ friend class ConcurrentGCPhaseManager;
+
+ public:
+ // Create an empty stack of phase managers.
+ Stack();
+
+ private:
+ int _requested_phase;
+ ConcurrentGCPhaseManager* _top;
+
+ // Non-copyable - never defined.
+ Stack(const Stack&);
+ Stack& operator=(const Stack&);
+ };
+
+ // Construct and push a new manager on the stack, activating phase.
+ // Notifies callers in wait_for_phase of the phase change.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - phase != UNCONSTRAINED_PHASE
+ // - stack != NULL
+ // - other managers on stack must all be active.
+ ConcurrentGCPhaseManager(int phase, Stack* stack);
+
+ // Pop this manager off the stack, deactivating phase. Before
+ // changing phases, if is_requested() is true, wait until the
+ // request is changed. After changing phases, notifies callers of
+ // wait_for_phase of the phase change.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - this must be the current top of the manager stack
+ ~ConcurrentGCPhaseManager();
+
+ // Returns true if this phase is active and is currently requested.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - this must be the current top of manager stack
+ bool is_requested() const;
+
+ // Wait until is_requested() is false. Returns true if waited.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - this must be the current top of manager stack
+ bool wait_when_requested() const;
+
+ // Directly step from one phase to another, without needing to pop a
+ // manager from the stack and allocate a new one. Before changing
+ // phases, if is_requested() is true and force is false, wait until
+ // the request is changed. After changing phases, notifies callers
+ // of wait_for_phase of the phase change.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - phase != UNCONSTRAINED_PHASE
+ // - this must be the current top of manager stack
+ void set_phase(int phase, bool force);
+
+ // Deactivate the manager. An inactive manager no longer blocks
+ // transitions out of the associated phase when that phase has been
+ // requested.
+ //
+ // Preconditions:
+ // - Calling thread must be a ConcurrentGC thread
+ // - this must be the current top of manager stack
+ void deactivate();
+
+ // Used to implement CollectorPolicy::request_concurrent_phase().
+ // Updates request to the new phase, and notifies threads blocked on
+ // the old request of the change. Returns true if the phase is
+ // UNCONSTRAINED_PHASE. Otherwise, waits until an active phase is
+ // the requested phase (returning true) or IDLE_PHASE (returning
+ // false if not also the requested phase).
+ //
+ // Preconditions:
+ // - Calling thread must be a Java thread
+ // - stack must be non-NULL
+ static bool wait_for_phase(int phase, Stack* stack);
+
+private:
+ int _phase;
+ bool _active;
+ ConcurrentGCPhaseManager* _prev;
+ Stack* _stack;
+
+ // Non-copyable - never defined.
+ ConcurrentGCPhaseManager(const ConcurrentGCPhaseManager&);
+ ConcurrentGCPhaseManager& operator=(const ConcurrentGCPhaseManager&);
+
+ bool wait_when_requested_impl() const;
+};
+
+#endif // include guard