You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by ad...@apache.org on 2016/07/14 18:03:25 UTC

[2/2] incubator-kudu git commit: rw_mutex: add configurable priority

rw_mutex: add configurable priority

The glibc implementation of pthread rwlocks exposes priorities that can help
if avoiding reader or writer starvation is desirable. I have a use case for
the latter, so let's expose the priorities in our wrapper.

Note: pthread rwlock priorities don't exist on macOS, which is why they're a
"best effort".

Change-Id: I16ba6cd041f126c94e63fa07a1e84c88db6778d7
Reviewed-on: http://gerrit.cloudera.org:8080/3603
Tested-by: Kudu Jenkins
Reviewed-by: Todd Lipcon <to...@apache.org>
Reviewed-by: Dan Burkert <da...@cloudera.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kudu/commit/71a5bb50
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kudu/tree/71a5bb50
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kudu/diff/71a5bb50

Branch: refs/heads/master
Commit: 71a5bb5070f144f8df356f5e28dd4e063de3df5e
Parents: 8c68d35
Author: Adar Dembo <ad...@cloudera.com>
Authored: Fri Jul 8 18:51:56 2016 -0700
Committer: Adar Dembo <ad...@cloudera.com>
Committed: Thu Jul 14 18:02:27 2016 +0000

----------------------------------------------------------------------
 src/kudu/util/rw_mutex.cc | 32 ++++++++++++++++++++++++++++++++
 src/kudu/util/rw_mutex.h  | 22 ++++++++++++++++++++++
 2 files changed, 54 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/71a5bb50/src/kudu/util/rw_mutex.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/rw_mutex.cc b/src/kudu/util/rw_mutex.cc
index b47d04f..d9473bb 100644
--- a/src/kudu/util/rw_mutex.cc
+++ b/src/kudu/util/rw_mutex.cc
@@ -31,8 +31,40 @@ void unlock_rwlock(pthread_rwlock_t* rwlock) {
 namespace kudu {
 
 RWMutex::RWMutex() {
+  Init(Priority::PREFER_READING);
+}
+
+RWMutex::RWMutex(Priority prio) {
+  Init(prio);
+}
+
+void RWMutex::Init(Priority prio) {
+#ifdef __linux__
+  // Adapt from priority to the pthread type.
+  int kind = PTHREAD_RWLOCK_PREFER_READER_NP;
+  switch (prio) {
+    case Priority::PREFER_READING:
+      kind = PTHREAD_RWLOCK_PREFER_READER_NP;
+      break;
+    case Priority::PREFER_WRITING:
+      kind = PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
+      break;
+  }
+
+  // Initialize the new rwlock with the user's preference.
+  pthread_rwlockattr_t attr;
+  int rv = pthread_rwlockattr_init(&attr);
+  DCHECK_EQ(0, rv) << strerror(rv);
+  rv = pthread_rwlockattr_setkind_np(&attr, kind);
+  DCHECK_EQ(0, rv) << strerror(rv);
+  rv = pthread_rwlock_init(&native_handle_, &attr);
+  DCHECK_EQ(0, rv) << strerror(rv);
+  rv = pthread_rwlockattr_destroy(&attr);
+  DCHECK_EQ(0, rv) << strerror(rv);
+#else
   int rv = pthread_rwlock_init(&native_handle_, NULL);
   DCHECK_EQ(0, rv) << strerror(rv);
+#endif
 }
 
 RWMutex::~RWMutex() {

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/71a5bb50/src/kudu/util/rw_mutex.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/rw_mutex.h b/src/kudu/util/rw_mutex.h
index 0153556..64a88d1 100644
--- a/src/kudu/util/rw_mutex.h
+++ b/src/kudu/util/rw_mutex.h
@@ -28,7 +28,27 @@ namespace kudu {
 // Implemented as a thin wrapper around pthread_rwlock_t.
 class RWMutex {
  public:
+
+  // Possible fairness policies for the RWMutex.
+  enum class Priority {
+    // The lock will prioritize readers at the expense of writers.
+    PREFER_READING,
+
+    // The lock will prioritize writers at the expense of readers.
+    //
+    // Care should be taken when using this fairness policy, as it can lead to
+    // unexpected deadlocks (e.g. a writer waiting on the lock will prevent
+    // additional readers from acquiring it).
+    PREFER_WRITING,
+  };
+
+  // Create an RWMutex that prioritizes readers.
   RWMutex();
+
+  // Create an RWMutex with customized priority. This is a best effort; the
+  // underlying platform may not support custom priorities.
+  explicit RWMutex(Priority prio);
+
   ~RWMutex();
 
   void ReadLock();
@@ -48,6 +68,8 @@ class RWMutex {
   bool try_lock_shared() { return TryReadLock(); }
 
  private:
+  void Init(Priority prio);
+
   pthread_rwlock_t native_handle_;
 
   DISALLOW_COPY_AND_ASSIGN(RWMutex);