1 /* 2 * Copyright (c) 2001, 2010, 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_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP 27 28 #ifndef SERIALGC 29 #include "runtime/thread.hpp" 30 #endif 31 32 class VoidClosure; 33 34 // A SuspendibleThreadSet is (obviously) a set of threads that can be 35 // suspended. A thread can join and later leave the set, and periodically 36 // yield. If some thread (not in the set) requests, via suspend_all, that 37 // the threads be suspended, then the requesting thread is blocked until 38 // all the threads in the set have yielded or left the set. (Threads may 39 // not enter the set when an attempted suspension is in progress.) The 40 // suspending thread later calls resume_all, allowing the suspended threads 41 // to continue. 42 43 class SuspendibleThreadSet { 44 Monitor* _m; 45 int _async; 46 bool _async_stop; 47 int _async_stopped; 48 bool _initialized; 49 double _suspend_all_start; 50 51 void initialize_work(); 52 53 public: 54 SuspendibleThreadSet() : _initialized(false) {} 55 56 // Add the current thread to the set. May block if a suspension 57 // is in progress. 58 void join(); 59 // Removes the current thread from the set. 60 void leave(); 61 // Returns "true" iff an suspension is in progress. 62 bool should_yield() { return _async_stop; } 63 // Suspends the current thread if a suspension is in progress (for 64 // the duration of the suspension.) 65 void yield(const char* id); 66 // Return when all threads in the set are suspended. 67 void suspend_all(); 68 // Allow suspended threads to resume. 69 void resume_all(); 70 // Redundant initializations okay. 71 void initialize() { 72 // Double-check dirty read idiom. 73 if (!_initialized) initialize_work(); 74 } 75 }; 76 77 78 class ConcurrentGCThread: public NamedThread { 79 friend class VMStructs; 80 81 protected: 82 bool _should_terminate; 83 bool _has_terminated; 84 85 enum CGC_flag_type { 86 CGC_nil = 0x0, 87 CGC_dont_suspend = 0x1, 88 CGC_CGC_safepoint = 0x2, 89 CGC_VM_safepoint = 0x4 90 }; 91 92 static int _CGC_flag; 93 94 static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; } 95 static int set_CGC_flag(int b) { return _CGC_flag |= b; } 96 static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; } 97 98 void stopWorldAndDo(VoidClosure* op); 99 100 // All instances share this one set. 101 static SuspendibleThreadSet _sts; 102 103 // Create and start the thread (setting it's priority high.) 104 void create_and_start(); 105 106 // Do initialization steps in the thread: record stack base and size, 107 // init thread local storage, set JNI handle block. 108 void initialize_in_thread(); 109 110 // Wait until Universe::is_fully_initialized(); 111 void wait_for_universe_init(); 112 113 // Record that the current thread is terminating, and will do more 114 // concurrent work. 115 void terminate(); 116 117 public: 118 // Constructor 119 120 ConcurrentGCThread(); 121 ~ConcurrentGCThread() {} // Exists to call NamedThread destructor. 122 123 // Tester 124 bool is_ConcurrentGC_thread() const { return true; } 125 126 static void safepoint_synchronize(); 127 static void safepoint_desynchronize(); 128 129 // All overridings should probably do _sts::yield, but we allow 130 // overriding for distinguished debugging messages. Default is to do 131 // nothing. 132 virtual void yield() {} 133 134 bool should_yield() { return _sts.should_yield(); } 135 136 // they are prefixed by sts since there are already yield() and 137 // should_yield() (non-static) methods in this class and it was an 138 // easy way to differentiate them. 139 static void stsYield(const char* id); 140 static bool stsShouldYield(); 141 static void stsJoin(); 142 static void stsLeave(); 143 144 }; 145 146 // The SurrogateLockerThread is used by concurrent GC threads for 147 // manipulating Java monitors, in particular, currently for 148 // manipulating the pending_list_lock. XXX 149 class SurrogateLockerThread: public JavaThread { 150 friend class VMStructs; 151 public: 152 enum SLT_msg_type { 153 empty = 0, // no message 154 acquirePLL, // acquire pending list lock 155 releaseAndNotifyPLL // notify and release pending list lock 156 }; 157 private: 158 // the following are shared with the CMSThread 159 SLT_msg_type _buffer; // communication buffer 160 Monitor _monitor; // monitor controlling buffer 161 BasicLock _basicLock; // used for PLL locking 162 163 public: 164 static SurrogateLockerThread* make(TRAPS); 165 166 SurrogateLockerThread(); 167 168 bool is_hidden_from_external_view() const { return true; } 169 170 void loop(); // main method 171 172 void manipulatePLL(SLT_msg_type msg); 173 174 }; 175 176 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP