< prev index next >

src/share/vm/runtime/mutex.cpp

Print this page


   1 /*
   2  * Copyright (c) 1998, 2014, 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  *


1018 // code -- a "PlatformMutex".  Alternatively, a simply layer over muxAcquire-muxRelease
1019 // would work too.
1020 //
1021 // Since the caller might be a foreign thread, we don't necessarily have a Thread.MutexEvent
1022 // instance available.  Instead, we transiently allocate a ParkEvent on-demand if
1023 // we encounter contention.  That ParkEvent remains associated with the thread
1024 // until it manages to acquire the lock, at which time we return the ParkEvent
1025 // to the global ParkEvent free list.  This is correct and suffices for our purposes.
1026 //
1027 // Beware that the original jvm_raw_unlock() had a "_snuck" test but that
1028 // jvm_raw_lock() didn't have the corresponding test.  I suspect that's an
1029 // oversight, but I've replicated the original suspect logic in the new code ...
1030 
1031 void Monitor::jvm_raw_lock() {
1032   assert(rank() == native, "invariant");
1033 
1034   if (TryLock()) {
1035  Exeunt:
1036     assert(ILocked(), "invariant");
1037     assert(_owner == NULL, "invariant");
1038     // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage
1039     // might return NULL. Don't call set_owner since it will break on an NULL owner
1040     // Consider installing a non-null "ANON" distinguished value instead of just NULL.
1041     _owner = ThreadLocalStorage::thread();
1042     return;
1043   }
1044 
1045   if (TrySpin(NULL)) goto Exeunt;
1046 
1047   // slow-path - apparent contention
1048   // Allocate a ParkEvent for transient use.
1049   // The ParkEvent remains associated with this thread until
1050   // the time the thread manages to acquire the lock.
1051   ParkEvent * const ESelf = ParkEvent::Allocate(NULL);
1052   ESelf->reset();
1053   OrderAccess::storeload();
1054 
1055   // Either Enqueue Self on cxq or acquire the outer lock.
1056   if (AcquireOrPush (ESelf)) {
1057     ParkEvent::Release(ESelf);      // surrender the ParkEvent
1058     goto Exeunt;
1059   }
1060 
1061   // At any given time there is at most one ondeck thread.


   1 /*
   2  * Copyright (c) 1998, 2015, 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  *


1018 // code -- a "PlatformMutex".  Alternatively, a simply layer over muxAcquire-muxRelease
1019 // would work too.
1020 //
1021 // Since the caller might be a foreign thread, we don't necessarily have a Thread.MutexEvent
1022 // instance available.  Instead, we transiently allocate a ParkEvent on-demand if
1023 // we encounter contention.  That ParkEvent remains associated with the thread
1024 // until it manages to acquire the lock, at which time we return the ParkEvent
1025 // to the global ParkEvent free list.  This is correct and suffices for our purposes.
1026 //
1027 // Beware that the original jvm_raw_unlock() had a "_snuck" test but that
1028 // jvm_raw_lock() didn't have the corresponding test.  I suspect that's an
1029 // oversight, but I've replicated the original suspect logic in the new code ...
1030 
1031 void Monitor::jvm_raw_lock() {
1032   assert(rank() == native, "invariant");
1033 
1034   if (TryLock()) {
1035  Exeunt:
1036     assert(ILocked(), "invariant");
1037     assert(_owner == NULL, "invariant");
1038     // This can potentially be called by non-java Threads. Thus, the Thread::current_or_null()
1039     // might return NULL. Don't call set_owner since it will break on an NULL owner
1040     // Consider installing a non-null "ANON" distinguished value instead of just NULL.
1041     _owner = Thread::current_or_null();
1042     return;
1043   }
1044 
1045   if (TrySpin(NULL)) goto Exeunt;
1046 
1047   // slow-path - apparent contention
1048   // Allocate a ParkEvent for transient use.
1049   // The ParkEvent remains associated with this thread until
1050   // the time the thread manages to acquire the lock.
1051   ParkEvent * const ESelf = ParkEvent::Allocate(NULL);
1052   ESelf->reset();
1053   OrderAccess::storeload();
1054 
1055   // Either Enqueue Self on cxq or acquire the outer lock.
1056   if (AcquireOrPush (ESelf)) {
1057     ParkEvent::Release(ESelf);      // surrender the ParkEvent
1058     goto Exeunt;
1059   }
1060 
1061   // At any given time there is at most one ondeck thread.


< prev index next >