Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/shared/concurrentGCThread.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 4ca6dc0799b6 4e4ebe50c8e3 |
children |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
34 | 34 |
35 // CopyrightVersion 1.2 | 35 // CopyrightVersion 1.2 |
36 | 36 |
37 int ConcurrentGCThread::_CGC_flag = CGC_nil; | 37 int ConcurrentGCThread::_CGC_flag = CGC_nil; |
38 | 38 |
39 SuspendibleThreadSet ConcurrentGCThread::_sts; | |
40 | |
41 ConcurrentGCThread::ConcurrentGCThread() : | 39 ConcurrentGCThread::ConcurrentGCThread() : |
42 _should_terminate(false), _has_terminated(false) { | 40 _should_terminate(false), _has_terminated(false) { |
43 _sts.initialize(); | |
44 }; | 41 }; |
45 | |
46 void ConcurrentGCThread::safepoint_synchronize() { | |
47 _sts.suspend_all(); | |
48 } | |
49 | |
50 void ConcurrentGCThread::safepoint_desynchronize() { | |
51 _sts.resume_all(); | |
52 } | |
53 | 42 |
54 void ConcurrentGCThread::create_and_start() { | 43 void ConcurrentGCThread::create_and_start() { |
55 if (os::create_thread(this, os::cgc_thread)) { | 44 if (os::create_thread(this, os::cgc_thread)) { |
56 // XXX: need to set this to low priority | 45 // XXX: need to set this to low priority |
57 // unless "agressive mode" set; priority | 46 // unless "agressive mode" set; priority |
87 Terminator_lock->notify(); | 76 Terminator_lock->notify(); |
88 } | 77 } |
89 | 78 |
90 // Thread destructor usually does this.. | 79 // Thread destructor usually does this.. |
91 ThreadLocalStorage::set_thread(NULL); | 80 ThreadLocalStorage::set_thread(NULL); |
92 } | |
93 | |
94 | |
95 void SuspendibleThreadSet::initialize_work() { | |
96 MutexLocker x(STS_init_lock); | |
97 if (!_initialized) { | |
98 _m = new Monitor(Mutex::leaf, | |
99 "SuspendibleThreadSetLock", true); | |
100 _async = 0; | |
101 _async_stop = false; | |
102 _async_stopped = 0; | |
103 _initialized = true; | |
104 } | |
105 } | |
106 | |
107 void SuspendibleThreadSet::join() { | |
108 initialize(); | |
109 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
110 while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); | |
111 _async++; | |
112 assert(_async > 0, "Huh."); | |
113 } | |
114 | |
115 void SuspendibleThreadSet::leave() { | |
116 assert(_initialized, "Must be initialized."); | |
117 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
118 _async--; | |
119 assert(_async >= 0, "Huh."); | |
120 if (_async_stop) _m->notify_all(); | |
121 } | |
122 | |
123 void SuspendibleThreadSet::yield(const char* id) { | |
124 assert(_initialized, "Must be initialized."); | |
125 if (_async_stop) { | |
126 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
127 if (_async_stop) { | |
128 _async_stopped++; | |
129 assert(_async_stopped > 0, "Huh."); | |
130 if (_async_stopped == _async) { | |
131 if (ConcGCYieldTimeout > 0) { | |
132 double now = os::elapsedTime(); | |
133 guarantee((now - _suspend_all_start) * 1000.0 < | |
134 (double)ConcGCYieldTimeout, | |
135 "Long delay; whodunit?"); | |
136 } | |
137 } | |
138 _m->notify_all(); | |
139 while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); | |
140 _async_stopped--; | |
141 assert(_async >= 0, "Huh"); | |
142 _m->notify_all(); | |
143 } | |
144 } | |
145 } | |
146 | |
147 void SuspendibleThreadSet::suspend_all() { | |
148 initialize(); // If necessary. | |
149 if (ConcGCYieldTimeout > 0) { | |
150 _suspend_all_start = os::elapsedTime(); | |
151 } | |
152 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
153 assert(!_async_stop, "Only one at a time."); | |
154 _async_stop = true; | |
155 while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag); | |
156 } | |
157 | |
158 void SuspendibleThreadSet::resume_all() { | |
159 assert(_initialized, "Must be initialized."); | |
160 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); | |
161 assert(_async_stopped == _async, "Huh."); | |
162 _async_stop = false; | |
163 _m->notify_all(); | |
164 } | 81 } |
165 | 82 |
166 static void _sltLoop(JavaThread* thread, TRAPS) { | 83 static void _sltLoop(JavaThread* thread, TRAPS) { |
167 SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; | 84 SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; |
168 slt->loop(); | 85 slt->loop(); |
218 } | 135 } |
219 os::yield(); // This seems to help with initial start-up of SLT | 136 os::yield(); // This seems to help with initial start-up of SLT |
220 return res; | 137 return res; |
221 } | 138 } |
222 | 139 |
140 void SurrogateLockerThread::report_missing_slt() { | |
141 vm_exit_during_initialization( | |
142 "GC before GC support fully initialized: " | |
143 "SLT is needed but has not yet been created."); | |
144 ShouldNotReachHere(); | |
145 } | |
146 | |
223 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { | 147 void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { |
224 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); | 148 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); |
225 assert(_buffer == empty, "Should be empty"); | 149 assert(_buffer == empty, "Should be empty"); |
226 assert(msg != empty, "empty message"); | 150 assert(msg != empty, "empty message"); |
227 assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread"); | 151 assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread"); |
280 _monitor.notify(); | 204 _monitor.notify(); |
281 } | 205 } |
282 } | 206 } |
283 assert(!_monitor.owned_by_self(), "Should unlock before exit."); | 207 assert(!_monitor.owned_by_self(), "Should unlock before exit."); |
284 } | 208 } |
285 | |
286 | |
287 // ===== STS Access From Outside CGCT ===== | |
288 | |
289 void ConcurrentGCThread::stsYield(const char* id) { | |
290 assert( Thread::current()->is_ConcurrentGC_thread(), | |
291 "only a conc GC thread can call this" ); | |
292 _sts.yield(id); | |
293 } | |
294 | |
295 bool ConcurrentGCThread::stsShouldYield() { | |
296 assert( Thread::current()->is_ConcurrentGC_thread(), | |
297 "only a conc GC thread can call this" ); | |
298 return _sts.should_yield(); | |
299 } | |
300 | |
301 void ConcurrentGCThread::stsJoin() { | |
302 assert( Thread::current()->is_ConcurrentGC_thread(), | |
303 "only a conc GC thread can call this" ); | |
304 _sts.join(); | |
305 } | |
306 | |
307 void ConcurrentGCThread::stsLeave() { | |
308 assert( Thread::current()->is_ConcurrentGC_thread(), | |
309 "only a conc GC thread can call this" ); | |
310 _sts.leave(); | |
311 } |