100 while (!_has_terminated) { |
100 while (!_has_terminated) { |
101 Terminator_lock->wait(); |
101 Terminator_lock->wait(); |
102 } |
102 } |
103 } |
103 } |
104 } |
104 } |
105 |
|
106 static void _sltLoop(JavaThread* thread, TRAPS) { |
|
107 SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; |
|
108 slt->loop(); |
|
109 } |
|
110 |
|
111 SurrogateLockerThread::SurrogateLockerThread() : |
|
112 JavaThread(&_sltLoop), |
|
113 _monitor(Mutex::nonleaf, "SLTMonitor", false, |
|
114 Monitor::_safepoint_check_sometimes), |
|
115 _buffer(empty) |
|
116 {} |
|
117 |
|
118 SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) { |
|
119 Klass* k = |
|
120 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), |
|
121 true, CHECK_NULL); |
|
122 instanceKlassHandle klass (THREAD, k); |
|
123 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); |
|
124 |
|
125 const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)"; |
|
126 Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL); |
|
127 |
|
128 // Initialize thread_oop to put it into the system threadGroup |
|
129 Handle thread_group (THREAD, Universe::system_thread_group()); |
|
130 JavaValue result(T_VOID); |
|
131 JavaCalls::call_special(&result, thread_oop, |
|
132 klass, |
|
133 vmSymbols::object_initializer_name(), |
|
134 vmSymbols::threadgroup_string_void_signature(), |
|
135 thread_group, |
|
136 string, |
|
137 CHECK_NULL); |
|
138 |
|
139 SurrogateLockerThread* res; |
|
140 { |
|
141 MutexLocker mu(Threads_lock); |
|
142 res = new SurrogateLockerThread(); |
|
143 |
|
144 // At this point it may be possible that no osthread was created for the |
|
145 // JavaThread due to lack of memory. We would have to throw an exception |
|
146 // in that case. However, since this must work and we do not allow |
|
147 // exceptions anyway, check and abort if this fails. |
|
148 if (res == NULL || res->osthread() == NULL) { |
|
149 vm_exit_during_initialization("java.lang.OutOfMemoryError", |
|
150 os::native_thread_creation_failed_msg()); |
|
151 } |
|
152 java_lang_Thread::set_thread(thread_oop(), res); |
|
153 java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); |
|
154 java_lang_Thread::set_daemon(thread_oop()); |
|
155 |
|
156 res->set_threadObj(thread_oop()); |
|
157 Threads::add(res); |
|
158 Thread::start(res); |
|
159 } |
|
160 os::naked_yield(); // This seems to help with initial start-up of SLT |
|
161 return res; |
|
162 } |
|
163 |
|
164 void SurrogateLockerThread::report_missing_slt() { |
|
165 vm_exit_during_initialization( |
|
166 "GC before GC support fully initialized: " |
|
167 "SLT is needed but has not yet been created."); |
|
168 ShouldNotReachHere(); |
|
169 } |
|
170 |
|
171 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { |
|
172 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); |
|
173 assert(_buffer == empty, "Should be empty"); |
|
174 assert(msg != empty, "empty message"); |
|
175 assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread"); |
|
176 |
|
177 _buffer = msg; |
|
178 while (_buffer != empty) { |
|
179 _monitor.notify(); |
|
180 _monitor.wait(Mutex::_no_safepoint_check_flag); |
|
181 } |
|
182 } |
|
183 |
|
184 // ======= Surrogate Locker Thread ============= |
|
185 |
|
186 void SurrogateLockerThread::loop() { |
|
187 BasicLock pll_basic_lock; |
|
188 SLT_msg_type msg; |
|
189 debug_only(unsigned int owned = 0;) |
|
190 |
|
191 while (/* !isTerminated() */ 1) { |
|
192 { |
|
193 MutexLocker x(&_monitor); |
|
194 // Since we are a JavaThread, we can't be here at a safepoint. |
|
195 assert(!SafepointSynchronize::is_at_safepoint(), |
|
196 "SLT is a JavaThread"); |
|
197 // wait for msg buffer to become non-empty |
|
198 while (_buffer == empty) { |
|
199 _monitor.notify(); |
|
200 _monitor.wait(); |
|
201 } |
|
202 msg = _buffer; |
|
203 } |
|
204 switch(msg) { |
|
205 case acquirePLL: { |
|
206 InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock); |
|
207 debug_only(owned++;) |
|
208 break; |
|
209 } |
|
210 case releaseAndNotifyPLL: { |
|
211 assert(owned > 0, "Don't have PLL"); |
|
212 InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock); |
|
213 debug_only(owned--;) |
|
214 break; |
|
215 } |
|
216 case empty: |
|
217 default: { |
|
218 guarantee(false,"Unexpected message in _buffer"); |
|
219 break; |
|
220 } |
|
221 } |
|
222 { |
|
223 MutexLocker x(&_monitor); |
|
224 // Since we are a JavaThread, we can't be here at a safepoint. |
|
225 assert(!SafepointSynchronize::is_at_safepoint(), |
|
226 "SLT is a JavaThread"); |
|
227 _buffer = empty; |
|
228 _monitor.notify(); |
|
229 } |
|
230 } |
|
231 assert(!_monitor.owned_by_self(), "Should unlock before exit."); |
|
232 } |
|