151 #endif
152
153 extern Mutex* tty_lock; // lock to synchronize output.
154
155 // A MutexLocker provides mutual exclusion with respect to a given mutex
156 // for the scope which contains the locker. The lock is an OS lock, not
157 // an object lock, and the two do not interoperate. Do not use Mutex-based
158 // locks to lock on Java objects, because they will not be respected if a
159 // that object is locked using the Java locking mechanism.
160 //
161 // NOTE WELL!!
162 //
163 // See orderAccess.hpp. We assume throughout the VM that MutexLocker's
164 // and friends constructors do a fence, a lock and an acquire *in that
165 // order*. And that their destructors do a release and unlock, in *that*
166 // order. If their implementations change such that these assumptions
167 // are violated, a whole lot of code will break.
168
169 // Print all mutexes/monitors that are currently owned by a thread; called
170 // by fatal error handler.
171 void print_owned_locks_on_error(outputStream* st);
172
173 char *lock_name(Mutex *mutex);
174
175 // for debugging: check that we're already owning this lock (or are at a safepoint)
176 #ifdef ASSERT
177 void assert_locked_or_safepoint(const Mutex* lock);
178 void assert_locked_or_safepoint_weak(const Mutex* lock);
179 void assert_lock_strong(const Mutex* lock);
180 #else
181 #define assert_locked_or_safepoint(lock)
182 #define assert_locked_or_safepoint_weak(lock)
183 #define assert_lock_strong(lock)
184 #endif
185
186 class MutexLocker: public StackObj {
187 protected:
188 Mutex* _mutex;
189 private:
190 public:
191 MutexLocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
192 _mutex(mutex) {
193 bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
194 if (_mutex != NULL) {
195 assert(_mutex->rank() > Mutex::special || no_safepoint_check,
196 "Mutexes with rank special or lower should not do safepoint checks");
197 if (no_safepoint_check) {
198 _mutex->lock_without_safepoint_check();
199 } else {
200 _mutex->lock();
201 }
202 }
203 }
204
205 MutexLocker(Mutex* mutex, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
206 _mutex(mutex) {
207 bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
208 if (_mutex != NULL) {
209 assert(_mutex->rank() > Mutex::special || no_safepoint_check,
210 "Mutexes with rank special or lower should not do safepoint checks");
211 if (no_safepoint_check) {
212 _mutex->lock_without_safepoint_check(thread);
213 } else {
214 _mutex->lock(thread);
215 }
216 }
217 }
218
219 ~MutexLocker() {
220 if (_mutex != NULL) {
221 assert_lock_strong(_mutex);
222 _mutex->unlock();
223 }
224 }
225 };
226
227 // A MonitorLocker is like a MutexLocker above, except it allows
228 // wait/notify as well which are delegated to the underlying Monitor.
229 // It also disallows NULL.
230
231 class MonitorLocker: public MutexLocker {
232 Mutex::SafepointCheckFlag _flag;
233 Monitor* _monitor;
234 public:
235 MonitorLocker(Monitor* monitor, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
236 MutexLocker(monitor, flag), _flag(flag), _monitor(monitor) {
237 // Superclass constructor did locking
238 assert(_monitor != NULL, "NULL monitor not allowed");
239 }
240
241 MonitorLocker(Monitor* monitor, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
242 MutexLocker(monitor, thread, flag), _flag(flag), _monitor(monitor) {
243 // Superclass constructor did locking
244 assert(_monitor != NULL, "NULL monitor not allowed");
245 }
246
247 bool wait(long timeout = 0,
248 bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag) {
249 if (_flag == Mutex::_safepoint_check_flag) {
250 return _monitor->wait(timeout, as_suspend_equivalent);
251 } else {
252 return _monitor->wait_without_safepoint_check(timeout);
253 }
254 return false;
255 }
256
257 void notify_all() {
258 _monitor->notify_all();
259 }
260
261 void notify() {
262 _monitor->notify();
263 }
264 };
265
266
267 // A GCMutexLocker is usually initialized with a mutex that is
268 // automatically acquired in order to do GC. The function that
269 // synchronizes using a GCMutexLocker may be called both during and between
270 // GC's. Thus, it must acquire the mutex if GC is not in progress, but not
271 // if GC is in progress (since the mutex is already held on its behalf.)
272
273 class GCMutexLocker: public StackObj {
274 private:
275 Mutex* _mutex;
276 bool _locked;
277 public:
278 GCMutexLocker(Mutex* mutex);
279 ~GCMutexLocker() { if (_locked) _mutex->unlock(); }
280 };
281
282 // A MutexUnlocker temporarily exits a previously
283 // entered mutex for the scope which contains the unlocker.
284
285 class MutexUnlocker: StackObj {
286 private:
287 Mutex* _mutex;
288 bool _no_safepoint_check;
289
290 public:
291 MutexUnlocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
292 _mutex(mutex),
293 _no_safepoint_check(flag) {
294 _mutex->unlock();
295 }
296
297 ~MutexUnlocker() {
298 if (_no_safepoint_check) {
299 _mutex->lock_without_safepoint_check();
300 } else {
301 _mutex->lock();
302 }
303 }
304 };
305
306 #endif // SHARE_RUNTIME_MUTEXLOCKER_HPP
|
151 #endif
152
153 extern Mutex* tty_lock; // lock to synchronize output.
154
155 // A MutexLocker provides mutual exclusion with respect to a given mutex
156 // for the scope which contains the locker. The lock is an OS lock, not
157 // an object lock, and the two do not interoperate. Do not use Mutex-based
158 // locks to lock on Java objects, because they will not be respected if a
159 // that object is locked using the Java locking mechanism.
160 //
161 // NOTE WELL!!
162 //
163 // See orderAccess.hpp. We assume throughout the VM that MutexLocker's
164 // and friends constructors do a fence, a lock and an acquire *in that
165 // order*. And that their destructors do a release and unlock, in *that*
166 // order. If their implementations change such that these assumptions
167 // are violated, a whole lot of code will break.
168
169 // Print all mutexes/monitors that are currently owned by a thread; called
170 // by fatal error handler.
171
172 void print_owned_locks_on_error(outputStream* st);
173
174 char *lock_name(Mutex *mutex);
175
176 // for debugging: check that we're already owning this lock (or are at a safepoint)
177 #ifdef ASSERT
178 void assert_locked_or_safepoint(const Mutex* lock);
179 void assert_locked_or_safepoint_weak(const Mutex* lock);
180 void assert_lock_strong(const Mutex* lock);
181 #else
182 #define assert_locked_or_safepoint(lock)
183 #define assert_locked_or_safepoint_weak(lock)
184 #define assert_lock_strong(lock)
185 #endif
186
187 class MutexLocker: public StackObj {
188 protected:
189 Mutex* _mutex;
190 public:
191 MutexLocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag);
192 MutexLocker(Mutex* mutex, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag);
193 ~MutexLocker();
194 };
195
196 // A MonitorLocker is like a MutexLocker above, except it allows
197 // wait/notify as well which are delegated to the underlying Monitor.
198 // It also disallows NULL.
199
200 class MonitorLocker: public MutexLocker {
201 Mutex::SafepointCheckFlag _flag;
202 Monitor* _monitor;
203 public:
204 MonitorLocker(Monitor* monitor, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag);
205 MonitorLocker(Monitor* monitor, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag);
206 bool wait(long timeout = 0, bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag);
207 void notify_all();
208 void notify();
209 };
210
211
212 // A GCMutexLocker is usually initialized with a mutex that is
213 // automatically acquired in order to do GC. The function that
214 // synchronizes using a GCMutexLocker may be called both during and between
215 // GC's. Thus, it must acquire the mutex if GC is not in progress, but not
216 // if GC is in progress (since the mutex is already held on its behalf.)
217
218 class GCMutexLocker: public StackObj {
219 private:
220 Mutex* _mutex;
221 bool _locked;
222 public:
223 GCMutexLocker(Mutex* mutex);
224 ~GCMutexLocker();
225 };
226
227 // A MutexUnlocker temporarily exits a previously
228 // entered mutex for the scope which contains the unlocker.
229
230 class MutexUnlocker: StackObj {
231 private:
232 Mutex* _mutex;
233 bool _no_safepoint_check;
234
235 public:
236 MutexUnlocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag);
237 ~MutexUnlocker();
238 };
239
240 #endif // SHARE_RUNTIME_MUTEXLOCKER_HPP
|