src/hotspot/share/gc/z/zLock.inline.hpp
changeset 52653 ec92cbf2152b
parent 50525 767cdb97f103
child 58122 48d51def09f9
child 58678 9cf78a70fa4f
--- a/src/hotspot/share/gc/z/zLock.inline.hpp	Thu Nov 22 09:14:31 2018 +0100
+++ b/src/hotspot/share/gc/z/zLock.inline.hpp	Fri Nov 09 14:08:01 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,18 @@
 #define SHARE_GC_Z_ZLOCK_INLINE_HPP
 
 #include "gc/z/zLock.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
 
 inline ZLock::ZLock() {
   pthread_mutex_init(&_lock, NULL);
 }
 
+inline ZLock::~ZLock() {
+  pthread_mutex_destroy(&_lock);
+}
+
 inline void ZLock::lock() {
   pthread_mutex_lock(&_lock);
 }
@@ -42,12 +49,49 @@
   pthread_mutex_unlock(&_lock);
 }
 
-inline ZLocker::ZLocker(ZLock* lock) :
+inline ZReentrantLock::ZReentrantLock() :
+    _lock(),
+    _owner(NULL),
+    _count(0) {}
+
+inline void ZReentrantLock::lock() {
+  Thread* const thread = Thread::current();
+  Thread* const owner = Atomic::load(&_owner);
+
+  if (owner != thread) {
+    _lock.lock();
+    Atomic::store(thread, &_owner);
+  }
+
+  _count++;
+}
+
+inline void ZReentrantLock::unlock() {
+  assert(is_owned(), "Invalid owner");
+  assert(_count > 0, "Invalid count");
+
+  _count--;
+
+  if (_count == 0) {
+    Atomic::store((Thread*)NULL, &_owner);
+    _lock.unlock();
+  }
+}
+
+inline bool ZReentrantLock::is_owned() const {
+  Thread* const thread = Thread::current();
+  Thread* const owner = Atomic::load(&_owner);
+  return owner == thread;
+}
+
+template <typename T>
+inline ZLocker<T>::ZLocker(T* lock) :
     _lock(lock) {
   _lock->lock();
 }
 
-inline ZLocker::~ZLocker() {
+template <typename T>
+inline ZLocker<T>::~ZLocker() {
   _lock->unlock();
 }