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