1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_GC_CONCURRENTGCPHASEMANAGER_HPP 26 #define SHARE_VM_GC_CONCURRENTGCPHASEMANAGER_HPP 27 28 #include "memory/allocation.hpp" 29 30 // Manage concurrent phase information, to support WhiteBox testing. 31 // Managers are stack allocated. Managers may be nested, to support 32 // nested subphases. 33 class ConcurrentGCPhaseManager : public StackObj { 34 public: 35 36 // Special phase ids used by all GC's that use this facility. 37 static const int UNCONSTRAINED_PHASE = 0; // Unconstrained or no request. 38 static const int IDLE_PHASE = 1; // Concurrent processing is idle. 39 40 // Stack of phase managers. 41 class Stack VALUE_OBJ_CLASS_SPEC { 42 friend class ConcurrentGCPhaseManager; 43 44 public: 45 // Create an empty stack of phase managers. 46 Stack(); 47 48 private: 49 int _requested_phase; 50 ConcurrentGCPhaseManager* _top; 51 52 // Non-copyable - never defined. 53 Stack(const Stack&); 54 Stack& operator=(const Stack&); 55 }; 56 57 // Construct and push a new manager on the stack, activating phase. 58 // Notifies callers in wait_for_phase of the phase change. 59 // 60 // Preconditions: 61 // - Calling thread must be a ConcurrentGC thread 62 // - phase != UNCONSTRAINED_PHASE 63 // - stack != NULL 64 // - other managers on stack must all be active. 65 ConcurrentGCPhaseManager(int phase, Stack* stack); 66 67 // Pop this manager off the stack, deactivating phase. Before 68 // changing phases, if is_requested() is true, wait until the 69 // request is changed. After changing phases, notifies callers of 70 // wait_for_phase of the phase change. 71 // 72 // Preconditions: 73 // - Calling thread must be a ConcurrentGC thread 74 // - this must be the current top of the manager stack 75 ~ConcurrentGCPhaseManager(); 76 77 // Returns true if this phase is active and is currently requested. 78 // 79 // Preconditions: 80 // - Calling thread must be a ConcurrentGC thread 81 // - this must be the current top of manager stack 82 bool is_requested() const; 83 84 // Wait until is_requested() is false. Returns true if waited. 85 // 86 // Preconditions: 87 // - Calling thread must be a ConcurrentGC thread 88 // - this must be the current top of manager stack 89 bool wait_when_requested() const; 90 91 // Directly step from one phase to another, without needing to pop a 92 // manager from the stack and allocate a new one. Before changing 93 // phases, if is_requested() is true and force is false, wait until 94 // the request is changed. After changing phases, notifies callers 95 // of wait_for_phase of the phase change. 96 // 97 // Preconditions: 98 // - Calling thread must be a ConcurrentGC thread 99 // - phase != UNCONSTRAINED_PHASE 100 // - this must be the current top of manager stack 101 void set_phase(int phase, bool force); 102 103 // Deactivate the manager. An inactive manager no longer blocks 104 // transitions out of the associated phase when that phase has been 105 // requested. 106 // 107 // Preconditions: 108 // - Calling thread must be a ConcurrentGC thread 109 // - this must be the current top of manager stack 110 void deactivate(); 111 112 // Used to implement CollectorPolicy::request_concurrent_phase(). 113 // Updates request to the new phase, and notifies threads blocked on 114 // the old request of the change. Returns true if the phase is 115 // UNCONSTRAINED_PHASE. Otherwise, waits until an active phase is 116 // the requested phase (returning true) or IDLE_PHASE (returning 117 // false if not also the requested phase). 118 // 119 // Preconditions: 120 // - Calling thread must be a Java thread 121 // - stack must be non-NULL 122 static bool wait_for_phase(int phase, Stack* stack); 123 124 private: 125 int _phase; 126 bool _active; 127 ConcurrentGCPhaseManager* _prev; 128 Stack* _stack; 129 130 // Non-copyable - never defined. 131 ConcurrentGCPhaseManager(const ConcurrentGCPhaseManager&); 132 ConcurrentGCPhaseManager& operator=(const ConcurrentGCPhaseManager&); 133 134 bool wait_when_requested_impl() const; 135 }; 136 137 #endif // include guard