--- /dev/null 2017-02-06 22:16:02.409658130 -0500 +++ new/src/share/vm/gc/shared/concurrentGCPhaseManager.hpp 2017-02-17 20:09:49.814263292 -0500 @@ -0,0 +1,134 @@ +/* + * 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 { + int _phase; + bool _active; + int* _request; + ConcurrentGCPhaseManager* _link; + ConcurrentGCPhaseManager** _stack; + +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. + + // Initialize stack with this object as the base, 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 && *stack == NULL + // - request != NULL + ConcurrentGCPhaseManager(int phase, + ConcurrentGCPhaseManager** stack, + int* request); + + // Push this manager on the stack topped by prev, activating phase. + // Notifies callers in wait_for_phase of the phase change. + // + // Preconditions: + // - Calling thread must be a ConcurrentGC thread + // - phase != UNCONSTRAINED_PHASE + // - prev must be the current top of manager stack + // - prev must not have been deactivated + ConcurrentGCPhaseManager(int phase, ConcurrentGCPhaseManager* prev); + + // 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 + static bool wait_for_phase(int phase, + ConcurrentGCPhaseManager** stack, + int* request); + +private: + // Non-copyable - never defined. + ConcurrentGCPhaseManager(const ConcurrentGCPhaseManager&); + ConcurrentGCPhaseManager& operator=(const ConcurrentGCPhaseManager&); + + bool wait_when_requested_impl() const; +}; + +#endif // include guard