X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2FRWLock.h;fp=src%2Fceph%2Fsrc%2Fcommon%2FRWLock.h;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=fd8a2665ef18f657d4c9b4d2939e5ea908068cbe;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/common/RWLock.h b/src/ceph/src/common/RWLock.h deleted file mode 100644 index fd8a266..0000000 --- a/src/ceph/src/common/RWLock.h +++ /dev/null @@ -1,265 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2006 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - - - -#ifndef CEPH_RWLock_Posix__H -#define CEPH_RWLock_Posix__H - -#include -#include -#include -#include "lockdep.h" -#include "common/valgrind.h" - -#include - -class RWLock final -{ - mutable pthread_rwlock_t L; - std::string name; - mutable int id; - mutable std::atomic nrlock = { 0 }, nwlock = { 0 }; - bool track, lockdep; - - std::string unique_name(const char* name) const; - -public: - RWLock(const RWLock& other) = delete; - const RWLock& operator=(const RWLock& other) = delete; - - RWLock(const std::string &n, bool track_lock=true, bool ld=true, bool prioritize_write=false) - : name(n), id(-1), track(track_lock), - lockdep(ld) { -#if defined(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) - if (prioritize_write) { - pthread_rwlockattr_t attr; - pthread_rwlockattr_init(&attr); - // PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP - // Setting the lock kind to this avoids writer starvation as long as - // long as any read locking is not done in a recursive fashion. - pthread_rwlockattr_setkind_np(&attr, - PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - pthread_rwlock_init(&L, &attr); - } else -#endif - // Next block is in {} to possibly connect to the above if when code is used. - { - pthread_rwlock_init(&L, NULL); - } - ANNOTATE_BENIGN_RACE_SIZED(&id, sizeof(id), "RWLock lockdep id"); - ANNOTATE_BENIGN_RACE_SIZED(&nrlock, sizeof(nrlock), "RWlock nrlock"); - ANNOTATE_BENIGN_RACE_SIZED(&nwlock, sizeof(nwlock), "RWlock nwlock"); - if (lockdep && g_lockdep) id = lockdep_register(name.c_str()); - } - - bool is_locked() const { - assert(track); - return (nrlock > 0) || (nwlock > 0); - } - - bool is_wlocked() const { - assert(track); - return (nwlock > 0); - } - ~RWLock() { - // The following check is racy but we are about to destroy - // the object and we assume that there are no other users. - if (track) - assert(!is_locked()); - pthread_rwlock_destroy(&L); - if (lockdep && g_lockdep) { - lockdep_unregister(id); - } - } - - void unlock(bool lockdep=true) const { - if (track) { - if (nwlock > 0) { - nwlock--; - } else { - assert(nrlock > 0); - nrlock--; - } - } - if (lockdep && this->lockdep && g_lockdep) - id = lockdep_will_unlock(name.c_str(), id); - int r = pthread_rwlock_unlock(&L); - assert(r == 0); - } - - // read - void get_read() const { - if (lockdep && g_lockdep) id = lockdep_will_lock(name.c_str(), id); - int r = pthread_rwlock_rdlock(&L); - assert(r == 0); - if (lockdep && g_lockdep) id = lockdep_locked(name.c_str(), id); - if (track) - nrlock++; - } - bool try_get_read() const { - if (pthread_rwlock_tryrdlock(&L) == 0) { - if (track) - nrlock++; - if (lockdep && g_lockdep) id = lockdep_locked(name.c_str(), id); - return true; - } - return false; - } - void put_read() const { - unlock(); - } - - // write - void get_write(bool lockdep=true) { - if (lockdep && this->lockdep && g_lockdep) - id = lockdep_will_lock(name.c_str(), id); - int r = pthread_rwlock_wrlock(&L); - assert(r == 0); - if (lockdep && this->lockdep && g_lockdep) - id = lockdep_locked(name.c_str(), id); - if (track) - nwlock++; - - } - bool try_get_write(bool lockdep=true) { - if (pthread_rwlock_trywrlock(&L) == 0) { - if (lockdep && this->lockdep && g_lockdep) - id = lockdep_locked(name.c_str(), id); - if (track) - nwlock++; - return true; - } - return false; - } - void put_write() { - unlock(); - } - - void get(bool for_write) { - if (for_write) { - get_write(); - } else { - get_read(); - } - } - -public: - class RLocker { - const RWLock &m_lock; - - bool locked; - - public: - explicit RLocker(const RWLock& lock) : m_lock(lock) { - m_lock.get_read(); - locked = true; - } - void unlock() { - assert(locked); - m_lock.unlock(); - locked = false; - } - ~RLocker() { - if (locked) { - m_lock.unlock(); - } - } - }; - - class WLocker { - RWLock &m_lock; - - bool locked; - - public: - explicit WLocker(RWLock& lock) : m_lock(lock) { - m_lock.get_write(); - locked = true; - } - void unlock() { - assert(locked); - m_lock.unlock(); - locked = false; - } - ~WLocker() { - if (locked) { - m_lock.unlock(); - } - } - }; - - class Context { - RWLock& lock; - - public: - enum LockState { - Untaken = 0, - TakenForRead = 1, - TakenForWrite = 2, - }; - - private: - LockState state; - - public: - explicit Context(RWLock& l) : lock(l), state(Untaken) {} - Context(RWLock& l, LockState s) : lock(l), state(s) {} - - void get_write() { - assert(state == Untaken); - - lock.get_write(); - state = TakenForWrite; - } - - void get_read() { - assert(state == Untaken); - - lock.get_read(); - state = TakenForRead; - } - - void unlock() { - assert(state != Untaken); - lock.unlock(); - state = Untaken; - } - - void promote() { - assert(state == TakenForRead); - unlock(); - get_write(); - } - - LockState get_state() { return state; } - void set_state(LockState s) { - state = s; - } - - bool is_locked() { - return (state != Untaken); - } - - bool is_rlocked() { - return (state == TakenForRead); - } - - bool is_wlocked() { - return (state == TakenForWrite); - } - }; -}; - -#endif // !CEPH_RWLock_Posix__H