1 /* 2 * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP 26 27 #include "gc_implementation/shenandoah/shenandoahHeap.hpp" 28 #include "memory/allocation.hpp" 29 #include "runtime/thread.hpp" 30 31 class ShenandoahHeapLock { 32 private: 33 enum LockState { unlocked = 0, locked = 1 }; 34 35 char _pad0[DEFAULT_CACHE_LINE_SIZE]; 36 volatile int _state; 37 char _pad1[DEFAULT_CACHE_LINE_SIZE]; 38 volatile Thread* _owner; 39 char _pad2[DEFAULT_CACHE_LINE_SIZE]; 40 41 public: 42 ShenandoahHeapLock() : _state(unlocked), _owner(NULL) {}; 43 44 void lock() { 45 Thread::SpinAcquire(&_state, "Shenandoah Heap Lock"); 46 #ifdef ASSERT 47 assert(_state == locked, "must be locked"); 48 assert(_owner == NULL, "must not be owned"); 49 _owner = Thread::current(); 50 #endif 51 } 52 53 void unlock() { 54 #ifdef ASSERT 55 assert (_owner == Thread::current(), "sanity"); 56 _owner = NULL; 57 #endif 58 Thread::SpinRelease(&_state); 59 } 60 61 #ifdef ASSERT 62 void assert_owned_by_current_thread() { 63 assert(_state == locked, "must be locked"); 64 assert(_owner == Thread::current(), "must be owned by current thread"); 65 } 66 67 void assert_not_owned_by_current_thread() { 68 assert(_owner != Thread::current(), "must be not owned by current thread"); 69 } 70 71 void assert_owned_by_current_thread_or_safepoint() { 72 Thread* thr = Thread::current(); 73 assert((_state == locked && _owner == thr) || 74 (SafepointSynchronize::is_at_safepoint() && thr->is_VM_thread()), 75 "must own heap lock or by VM thread at safepoint"); 76 } 77 #endif 78 }; 79 80 class ShenandoahHeapLocker : public StackObj { 81 private: 82 ShenandoahHeapLock* _lock; 83 public: 84 ShenandoahHeapLocker(ShenandoahHeapLock* lock) { 85 _lock = lock; 86 _lock->lock(); 87 } 88 89 ~ShenandoahHeapLocker() { 90 _lock->unlock(); 91 } 92 }; 93 94 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPLOCK_HPP