]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/RWLock: allow disabling read/write lock counts
authorPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Wed, 17 Jun 2015 13:43:24 +0000 (15:43 +0200)
committerPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Wed, 17 Jun 2015 13:43:24 +0000 (15:43 +0200)
For some workloads, it is worthwile to disable adjusting of internal nrlock
and nwlock atomic variables (which isn't super cheap and may lock CPUs for
longer than with regular mutexes). Added new argument (track_locks) to
RWLock constuctor (with default value of True) which enables or disables
adjusting these variables if needed.
(R|W)Locker helper classes are around 40% faster when tracking is disabled
and direct get_read()/get_write()+unlock() methods are up to 120% faster
when tracking is disabled.

Signed-off-by: Piotr Dałek <piotr.dalek@ts.fujitsu.com>
src/common/RWLock.h

index c82a23cccc60c44920aaf744fc885e99c59ae70a..47a8c87f500a2440e6c90528a99f016d15567716 100644 (file)
@@ -29,6 +29,7 @@ class RWLock
   std::string name;
   mutable int id;
   mutable atomic_t nrlock, nwlock;
+  bool track;
 
   std::string unique_name(const char* name) const;
 
@@ -36,22 +37,25 @@ public:
   RWLock(const RWLock& other);
   const RWLock& operator=(const RWLock& other);
 
-  RWLock(const std::string &n) : name(n), id(-1), nrlock(0), nwlock(0) {
+  RWLock(const std::string &n, bool track_lock=true) : name(n), id(-1), nrlock(0), nwlock(0), track(track_lock) {
     pthread_rwlock_init(&L, NULL);
     if (g_lockdep) id = lockdep_register(name.c_str());
   }
 
   bool is_locked() const {
+    assert(track);
     return (nrlock.read() > 0) || (nwlock.read() > 0);
   }
 
   bool is_wlocked() const {
+    assert(track);
     return (nwlock.read() > 0);
   }
   virtual ~RWLock() {
     // The following check is racy but we are about to destroy
     // the object and we assume that there are no other users.
-    assert(!is_locked());
+    if (track)
+      assert(!is_locked());
     pthread_rwlock_destroy(&L);
     if (g_lockdep) {
       lockdep_unregister(id);
@@ -59,11 +63,13 @@ public:
   }
 
   void unlock(bool lockdep=true) const {
-    if (nwlock.read() > 0) {
-      nwlock.dec();
-    } else {
-      assert(nrlock.read() > 0);
-      nrlock.dec();
+    if (track) {
+      if (nwlock.read() > 0) {
+        nwlock.dec();
+      } else {
+        assert(nrlock.read() > 0);
+        nrlock.dec();
+      }
     }
     if (lockdep && g_lockdep) id = lockdep_will_unlock(name.c_str(), id);
     int r = pthread_rwlock_unlock(&L);
@@ -76,11 +82,13 @@ public:
     int r = pthread_rwlock_rdlock(&L);
     assert(r == 0);
     if (g_lockdep) id = lockdep_locked(name.c_str(), id);
-    nrlock.inc();
+    if (track)
+      nrlock.inc();
   }
   bool try_get_read() const {
     if (pthread_rwlock_tryrdlock(&L) == 0) {
-      nrlock.inc();
+      if (track)
+         nrlock.inc();
       if (g_lockdep) id = lockdep_locked(name.c_str(), id);
       return true;
     }
@@ -96,13 +104,15 @@ public:
     int r = pthread_rwlock_wrlock(&L);
     assert(r == 0);
     if (g_lockdep) id = lockdep_locked(name.c_str(), id);
-    nwlock.inc();
+    if (track)
+      nwlock.inc();
 
   }
   bool try_get_write(bool lockdep=true) {
     if (pthread_rwlock_trywrlock(&L) == 0) {
       if (lockdep && g_lockdep) id = lockdep_locked(name.c_str(), id);
-      nwlock.inc();
+      if (track)
+         nwlock.inc();
       return true;
     }
     return false;