From: Piotr Dałek Date: Wed, 17 Jun 2015 13:43:24 +0000 (+0200) Subject: common/RWLock: allow disabling read/write lock counts X-Git-Tag: v9.1.0~495^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8feb27d821c76d00f76064fa04559e493be7ac32;p=ceph.git common/RWLock: allow disabling read/write lock counts 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 --- diff --git a/src/common/RWLock.h b/src/common/RWLock.h index c82a23cccc6..47a8c87f500 100644 --- a/src/common/RWLock.h +++ b/src/common/RWLock.h @@ -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;