< prev index next >

src/hotspot/share/runtime/mutex.cpp

Print this page

        

*** 31,61 **** #include "runtime/thread.inline.hpp" #include "utilities/events.hpp" #include "utilities/macros.hpp" #ifdef ASSERT ! void Monitor::check_safepoint_state(Thread* thread, bool do_safepoint_check) { // If the JavaThread checks for safepoint, verify that the lock wasn't created with safepoint_check_never. ! SafepointCheckRequired not_allowed = do_safepoint_check ? Monitor::_safepoint_check_never : ! Monitor::_safepoint_check_always; assert(!thread->is_active_Java_thread() || _safepoint_check_required != not_allowed, "This lock should %s have a safepoint check for Java threads: %s", _safepoint_check_required ? "always" : "never", name()); // If defined with safepoint_check_never, a NonJavaThread should never ask to safepoint check either. ! assert(thread->is_Java_thread() || !do_safepoint_check || _safepoint_check_required != Monitor::_safepoint_check_never, "NonJavaThread should not check for safepoint"); } #endif // ASSERT ! void Monitor::lock(Thread * self) { check_safepoint_state(self, true); DEBUG_ONLY(check_prelock_state(self, true)); assert(_owner != self, "invariant"); ! Monitor* in_flight_monitor = NULL; DEBUG_ONLY(int retry_cnt = 0;) bool is_active_Java_thread = self->is_active_Java_thread(); while (!_lock.try_lock()) { // The lock is contended --- 31,61 ---- #include "runtime/thread.inline.hpp" #include "utilities/events.hpp" #include "utilities/macros.hpp" #ifdef ASSERT ! void Mutex::check_safepoint_state(Thread* thread, bool do_safepoint_check) { // If the JavaThread checks for safepoint, verify that the lock wasn't created with safepoint_check_never. ! SafepointCheckRequired not_allowed = do_safepoint_check ? Mutex::_safepoint_check_never : ! Mutex::_safepoint_check_always; assert(!thread->is_active_Java_thread() || _safepoint_check_required != not_allowed, "This lock should %s have a safepoint check for Java threads: %s", _safepoint_check_required ? "always" : "never", name()); // If defined with safepoint_check_never, a NonJavaThread should never ask to safepoint check either. ! assert(thread->is_Java_thread() || !do_safepoint_check || _safepoint_check_required != Mutex::_safepoint_check_never, "NonJavaThread should not check for safepoint"); } #endif // ASSERT ! void Mutex::lock(Thread * self) { check_safepoint_state(self, true); DEBUG_ONLY(check_prelock_state(self, true)); assert(_owner != self, "invariant"); ! Mutex* in_flight_monitor = NULL; DEBUG_ONLY(int retry_cnt = 0;) bool is_active_Java_thread = self->is_active_Java_thread(); while (!_lock.try_lock()) { // The lock is contended
*** 85,120 **** assert_owner(NULL); set_owner(self); } ! void Monitor::lock() { this->lock(Thread::current()); } // Lock without safepoint check - a degenerate variant of lock() for use by // JavaThreads when it is known to be safe to not check for a safepoint when // acquiring this lock. If the thread blocks acquiring the lock it is not // safepoint-safe and so will prevent a safepoint from being reached. If used // in the wrong way this can lead to a deadlock with the safepoint code. ! void Monitor::lock_without_safepoint_check(Thread * self) { check_safepoint_state(self, false); assert(_owner != self, "invariant"); _lock.lock(); assert_owner(NULL); set_owner(self); } ! void Monitor::lock_without_safepoint_check() { lock_without_safepoint_check(Thread::current()); } // Returns true if thread succeeds in grabbing the lock, otherwise false. ! bool Monitor::try_lock() { Thread * const self = Thread::current(); DEBUG_ONLY(check_prelock_state(self, false);) if (_lock.try_lock()) { assert_owner(NULL); --- 85,120 ---- assert_owner(NULL); set_owner(self); } ! void Mutex::lock() { this->lock(Thread::current()); } // Lock without safepoint check - a degenerate variant of lock() for use by // JavaThreads when it is known to be safe to not check for a safepoint when // acquiring this lock. If the thread blocks acquiring the lock it is not // safepoint-safe and so will prevent a safepoint from being reached. If used // in the wrong way this can lead to a deadlock with the safepoint code. ! void Mutex::lock_without_safepoint_check(Thread * self) { check_safepoint_state(self, false); assert(_owner != self, "invariant"); _lock.lock(); assert_owner(NULL); set_owner(self); } ! void Mutex::lock_without_safepoint_check() { lock_without_safepoint_check(Thread::current()); } // Returns true if thread succeeds in grabbing the lock, otherwise false. ! bool Mutex::try_lock() { Thread * const self = Thread::current(); DEBUG_ONLY(check_prelock_state(self, false);) if (_lock.try_lock()) { assert_owner(NULL);
*** 122,137 **** return true; } return false; } ! void Monitor::release_for_safepoint() { assert_owner(NULL); _lock.unlock(); } ! void Monitor::unlock() { assert_owner(Thread::current()); set_owner(NULL); _lock.unlock(); } --- 122,137 ---- return true; } return false; } ! void Mutex::release_for_safepoint() { assert_owner(NULL); _lock.unlock(); } ! void Mutex::unlock() { assert_owner(Thread::current()); set_owner(NULL); _lock.unlock(); }
*** 145,155 **** _lock.notify_all(); } #ifdef ASSERT void Monitor::assert_wait_lock_state(Thread* self) { ! Monitor* least = get_least_ranked_lock_besides_this(self->owned_locks()); assert(least != this, "Specification of get_least_... call above"); if (least != NULL && least->rank() <= special) { ::tty->print("Attempting to wait on monitor %s/%d while holding" " lock %s/%d -- possible deadlock", name(), rank(), least->name(), least->rank()); --- 145,155 ---- _lock.notify_all(); } #ifdef ASSERT void Monitor::assert_wait_lock_state(Thread* self) { ! Mutex* least = get_least_ranked_lock_besides_this(self->owned_locks()); assert(least != this, "Specification of get_least_... call above"); if (least != NULL && least->rank() <= special) { ::tty->print("Attempting to wait on monitor %s/%d while holding" " lock %s/%d -- possible deadlock", name(), rank(), least->name(), least->rank());
*** 192,202 **** int wait_status; // conceptually set the owner to NULL in anticipation of // abdicating the lock in wait set_owner(NULL); JavaThread *jt = (JavaThread *)self; ! Monitor* in_flight_monitor = NULL; { ThreadBlockInVMWithDeadlockCheck tbivmdc(jt, &in_flight_monitor); OSThreadWaitState osts(self->osthread(), false /* not Object.wait() */); if (as_suspend_equivalent) { --- 192,202 ---- int wait_status; // conceptually set the owner to NULL in anticipation of // abdicating the lock in wait set_owner(NULL); JavaThread *jt = (JavaThread *)self; ! Mutex* in_flight_monitor = NULL; { ThreadBlockInVMWithDeadlockCheck tbivmdc(jt, &in_flight_monitor); OSThreadWaitState osts(self->osthread(), false /* not Object.wait() */); if (as_suspend_equivalent) {
*** 230,249 **** } return wait_status != 0; // return true IFF timeout } ! Monitor::~Monitor() { assert_owner(NULL); } // Only Threads_lock, Heap_lock and SR_lock may be safepoint_check_sometimes. bool is_sometimes_ok(const char* name) { return (strcmp(name, "Threads_lock") == 0 || strcmp(name, "Heap_lock") == 0 || strcmp(name, "SR_lock") == 0); } ! Monitor::Monitor(int Rank, const char * name, bool allow_vm_block, SafepointCheckRequired safepoint_check_required) : _owner(NULL) { assert(os::mutex_init_done(), "Too early!"); if (name == NULL) { strcpy(_name, "UNKNOWN"); } else { --- 230,249 ---- } return wait_status != 0; // return true IFF timeout } ! Mutex::~Mutex() { assert_owner(NULL); } // Only Threads_lock, Heap_lock and SR_lock may be safepoint_check_sometimes. bool is_sometimes_ok(const char* name) { return (strcmp(name, "Threads_lock") == 0 || strcmp(name, "Heap_lock") == 0 || strcmp(name, "SR_lock") == 0); } ! Mutex::Mutex(int Rank, const char * name, bool allow_vm_block, SafepointCheckRequired safepoint_check_required) : _owner(NULL) { assert(os::mutex_init_done(), "Too early!"); if (name == NULL) { strcpy(_name, "UNKNOWN"); } else {
*** 253,295 **** #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank; _safepoint_check_required = safepoint_check_required; ! assert(_safepoint_check_required != Monitor::_safepoint_check_sometimes || is_sometimes_ok(name), "Lock has _safepoint_check_sometimes %s", name); #endif } ! Mutex::Mutex(int Rank, const char * name, bool allow_vm_block, SafepointCheckRequired safepoint_check_required) : ! Monitor(Rank, name, allow_vm_block, safepoint_check_required) {} ! bool Monitor::owned_by_self() const { return _owner == Thread::current(); } ! void Monitor::print_on_error(outputStream* st) const { st->print("[" PTR_FORMAT, p2i(this)); st->print("] %s", _name); st->print(" - owner thread: " PTR_FORMAT, p2i(_owner)); } // ---------------------------------------------------------------------------------- // Non-product code #ifndef PRODUCT ! void Monitor::print_on(outputStream* st) const { st->print_cr("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT, p2i(this), _name, p2i(_owner)); } #endif #ifndef PRODUCT #ifdef ASSERT ! void Monitor::assert_owner(Thread * expected) { const char* msg = "invalid owner"; if (expected == NULL) { msg = "should be un-owned"; } else if (expected == Thread::current()) { --- 253,295 ---- #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank; _safepoint_check_required = safepoint_check_required; ! assert(_safepoint_check_required != Mutex::_safepoint_check_sometimes || is_sometimes_ok(name), "Lock has _safepoint_check_sometimes %s", name); #endif } ! Monitor::Monitor(int Rank, const char * name, bool allow_vm_block, SafepointCheckRequired safepoint_check_required) : ! Mutex(Rank, name, allow_vm_block, safepoint_check_required) {} ! bool Mutex::owned_by_self() const { return _owner == Thread::current(); } ! void Mutex::print_on_error(outputStream* st) const { st->print("[" PTR_FORMAT, p2i(this)); st->print("] %s", _name); st->print(" - owner thread: " PTR_FORMAT, p2i(_owner)); } // ---------------------------------------------------------------------------------- // Non-product code #ifndef PRODUCT ! void Mutex::print_on(outputStream* st) const { st->print_cr("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT, p2i(this), _name, p2i(_owner)); } #endif #ifndef PRODUCT #ifdef ASSERT ! void Mutex::assert_owner(Thread * expected) { const char* msg = "invalid owner"; if (expected == NULL) { msg = "should be un-owned"; } else if (expected == Thread::current()) {
*** 298,309 **** assert(_owner == expected, "%s: owner=" INTPTR_FORMAT ", should be=" INTPTR_FORMAT, msg, p2i(_owner), p2i(expected)); } ! Monitor * Monitor::get_least_ranked_lock(Monitor * locks) { ! Monitor *res, *tmp; for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) { if (tmp->rank() < res->rank()) { res = tmp; } } --- 298,309 ---- assert(_owner == expected, "%s: owner=" INTPTR_FORMAT ", should be=" INTPTR_FORMAT, msg, p2i(_owner), p2i(expected)); } ! Mutex* Mutex::get_least_ranked_lock(Mutex* locks) { ! Mutex *res, *tmp; for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) { if (tmp->rank() < res->rank()) { res = tmp; } }
*** 318,329 **** } } return res; } ! Monitor* Monitor::get_least_ranked_lock_besides_this(Monitor* locks) { ! Monitor *res, *tmp; for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) { if (tmp != this && (res == NULL || tmp->rank() < res->rank())) { res = tmp; } } --- 318,329 ---- } } return res; } ! Mutex* Mutex::get_least_ranked_lock_besides_this(Mutex* locks) { ! Mutex *res, *tmp; for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) { if (tmp != this && (res == NULL || tmp->rank() < res->rank())) { res = tmp; } }
*** 339,349 **** } return res; } ! bool Monitor::contains(Monitor* locks, Monitor * lock) { for (; locks != NULL; locks = locks->next()) { if (locks == lock) { return true; } } --- 339,349 ---- } return res; } ! bool Mutex::contains(Mutex* locks, Mutex* lock) { for (; locks != NULL; locks = locks->next()) { if (locks == lock) { return true; } }
*** 354,364 **** // Called immediately after lock acquisition or release as a diagnostic // to track the lock-set of the thread and test for rank violations that // might indicate exposure to deadlock. // Rather like an EventListener for _owner (:>). ! void Monitor::set_owner_implementation(Thread *new_owner) { // This function is solely responsible for maintaining // and checking the invariant that threads and locks // are in a 1/N relation, with some some locks unowned. // It uses the Mutex::_owner, Mutex::_next, and // Thread::_owned_locks fields, and no other function --- 354,364 ---- // Called immediately after lock acquisition or release as a diagnostic // to track the lock-set of the thread and test for rank violations that // might indicate exposure to deadlock. // Rather like an EventListener for _owner (:>). ! void Mutex::set_owner_implementation(Thread *new_owner) { // This function is solely responsible for maintaining // and checking the invariant that threads and locks // are in a 1/N relation, with some some locks unowned. // It uses the Mutex::_owner, Mutex::_next, and // Thread::_owned_locks fields, and no other function
*** 375,385 **** _owner = new_owner; // set the owner // link "this" into the owned locks list #ifdef ASSERT // Thread::_owned_locks is under the same ifdef ! Monitor* locks = get_least_ranked_lock(new_owner->owned_locks()); // Mutex::set_owner_implementation is a friend of Thread assert(this->rank() >= 0, "bad lock rank"); // Deadlock avoidance rules require us to acquire Mutexes only in --- 375,385 ---- _owner = new_owner; // set the owner // link "this" into the owned locks list #ifdef ASSERT // Thread::_owned_locks is under the same ifdef ! Mutex* locks = get_least_ranked_lock(new_owner->owned_locks()); // Mutex::set_owner_implementation is a friend of Thread assert(this->rank() >= 0, "bad lock rank"); // Deadlock avoidance rules require us to acquire Mutexes only in
*** 413,427 **** assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex"); _owner = NULL; // set the owner #ifdef ASSERT ! Monitor *locks = old_owner->owned_locks(); // remove "this" from the owned locks list ! Monitor *prev = NULL; bool found = false; for (; locks != NULL; prev = locks, locks = locks->next()) { if (locks == this) { found = true; break; --- 413,427 ---- assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex"); _owner = NULL; // set the owner #ifdef ASSERT ! Mutex* locks = old_owner->owned_locks(); // remove "this" from the owned locks list ! Mutex* prev = NULL; bool found = false; for (; locks != NULL; prev = locks, locks = locks->next()) { if (locks == this) { found = true; break;
*** 438,448 **** } } // Factored out common sanity checks for locking mutex'es. Used by lock() and try_lock() ! void Monitor::check_prelock_state(Thread *thread, bool safepoint_check) { if (safepoint_check) { assert((!thread->is_active_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm) || rank() == Mutex::special, "wrong thread state for using locks"); if (thread->is_VM_thread() && !allow_vm_block()) { fatal("VM thread using lock %s (not allowed to block on)", name()); --- 438,448 ---- } } // Factored out common sanity checks for locking mutex'es. Used by lock() and try_lock() ! void Mutex::check_prelock_state(Thread *thread, bool safepoint_check) { if (safepoint_check) { assert((!thread->is_active_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm) || rank() == Mutex::special, "wrong thread state for using locks"); if (thread->is_VM_thread() && !allow_vm_block()) { fatal("VM thread using lock %s (not allowed to block on)", name());
*** 452,462 **** } assert(!os::ThreadCrashProtection::is_crash_protected(thread), "locking not allowed when crash protection is set"); } ! void Monitor::check_block_state(Thread *thread) { if (!_allow_vm_block && thread->is_VM_thread()) { warning("VM thread blocked on lock"); print(); BREAKPOINT; } --- 452,462 ---- } assert(!os::ThreadCrashProtection::is_crash_protected(thread), "locking not allowed when crash protection is set"); } ! void Mutex::check_block_state(Thread *thread) { if (!_allow_vm_block && thread->is_VM_thread()) { warning("VM thread blocked on lock"); print(); BREAKPOINT; }
< prev index next >