Commit 28112766 by Elvin Sindrilaru

COMMON: Update RWMutex interface and use more consistent naming

parent f5186d8b
......@@ -46,27 +46,23 @@ public:
virtual void SetBlocking(bool block) = 0;
//----------------------------------------------------------------------------
//! Set the time to wait for the acquisition of the write mutex before
//! releasing quicky and retrying.
//!
//! @param nsec nanoseconds
//----------------------------------------------------------------------------
virtual void SetWLockTime(const size_t& nsec) = 0;
//----------------------------------------------------------------------------
//! Lock for read
//----------------------------------------------------------------------------
virtual void LockRead() = 0;
//----------------------------------------------------------------------------
//! Lock for read allowing to be canceled waiting for the lock
//! Unlock a read lock
//----------------------------------------------------------------------------
virtual void LockReadCancel() = 0;
virtual void UnLockRead() = 0;
//----------------------------------------------------------------------------
//! Unlock a read lock
//! Try to read lock the mutex within the timeout
//!
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
virtual void UnLockRead() = 0;
virtual int TimedRdLock(uint64_t timeout_ns) = 0;
//----------------------------------------------------------------------------
//! Lock for write
......@@ -79,28 +75,23 @@ public:
virtual void UnLockWrite() = 0;
//----------------------------------------------------------------------------
//! Try to read lock the mutex within the timout value
//! Try to write lock the mutex within the timeout
//!
//! @param timeout_ms time duration in milliseconds we can wait for the lock
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if lock aquired, ETIMEOUT if timeout occured
//----------------------------------------------------------------------------
virtual int TimedRdLock(uint64_t timeout_ms) = 0;
//----------------------------------------------------------------------------
//! Lock for write but give up after wlocktime
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
virtual int TimeoutLockWrite() = 0;
virtual int TimedWrLock(uint64_t timeout_ns) = 0;
//----------------------------------------------------------------------------
//! Get Readlock Counter
//! Get read lock counter
//----------------------------------------------------------------------------
virtual size_t GetReadLockCounter() = 0;
virtual uint64_t GetReadLockCounter() = 0;
//----------------------------------------------------------------------------
//! Get Writelock Counter
//! Get write lock counter
//----------------------------------------------------------------------------
virtual size_t GetWriteLockCounter() = 0;
virtual uint64_t GetWriteLockCounter() = 0;
};
EOSCOMMONNAMESPACE_END
......@@ -121,9 +121,6 @@ PthreadRWMutex::PthreadRWMutex(bool prefer_rd):
// Try to get write lock in 5 seconds, then release quickly and retry
wlocktime.tv_sec = 5;
wlocktime.tv_nsec = 0;
// Try to get read lock in 100ms, otherwise allow this thread to be canceled
rlocktime.tv_sec = 0;
rlocktime.tv_nsec = 1000000;
#ifdef EOS_INSTRUMENTED_RWMUTEX
mSamplingModulo = 300;
......@@ -221,7 +218,7 @@ PthreadRWMutex::~PthreadRWMutex()
// Try to read lock the mutex within the timout value
//------------------------------------------------------------------------------
int
PthreadRWMutex::TimedRdLock(uint64_t timeout_ms)
PthreadRWMutex::TimedRdLock(uint64_t timeout_ns)
{
EOS_RWMUTEX_CHECKORDER_LOCK;
EOS_RWMUTEX_TIMER_START;
......@@ -240,11 +237,14 @@ PthreadRWMutex::TimedRdLock(uint64_t timeout_ms)
struct timespec timeout = {0};
_clock_gettime(CLOCK_REALTIME, &timeout);
if (timeout_ms > 1000) {
timeout.tv_sec += (timeout_ms / 1000);
if (timeout_ns) {
if (timeout_ns > 1e9) {
timeout.tv_sec += (timeout_ns / 1e9);
}
timeout.tv_nsec += (timeout_ns % (unsigned long long)1e9);
}
timeout.tv_nsec += (timeout_ms % 1000) * 1000000;
#ifdef __APPLE__
// Mac does not support timed mutexes
retc = pthread_rwlock_rdlock(&rwlock);
......@@ -265,7 +265,7 @@ PthreadRWMutex::TimedRdLock(uint64_t timeout_ms)
//----------------------------------------------------------------------------
// Get Writelock Counter
//----------------------------------------------------------------------------
size_t
uint64_t
PthreadRWMutex::GetWriteLockCounter()
{
return AtomicGet(mWrLockCounter);
......@@ -274,22 +274,12 @@ PthreadRWMutex::GetWriteLockCounter()
//----------------------------------------------------------------------------
// Get ReadLock Counter
//----------------------------------------------------------------------------
size_t
uint64_t
PthreadRWMutex::GetReadLockCounter()
{
return AtomicGet(mRdLockCounter);
}
//------------------------------------------------------------------------------
// Set the time to wait for the acquisition of the write mutex before releasing
// quicky and retrying.
//------------------------------------------------------------------------------
void
PthreadRWMutex::SetWLockTime(const size_t& nsec)
{
wlocktime.tv_sec = nsec / 1000000;
wlocktime.tv_nsec = nsec % 1000000;
}
//------------------------------------------------------------------------------
// Lock for read
......@@ -321,49 +311,6 @@ PthreadRWMutex::LockRead()
EOS_RWMUTEX_TIMER_STOP_AND_UPDATE(mRd);
}
//------------------------------------------------------------------------------
// Lock for read allowing to be canceled waiting for a lock
//------------------------------------------------------------------------------
void
PthreadRWMutex::LockReadCancel()
{
EOS_RWMUTEX_CHECKORDER_LOCK;
EOS_RWMUTEX_TIMER_START;
#ifndef __APPLE__
while (1) {
struct timespec readtimeout = {0};
_clock_gettime(CLOCK_REALTIME, &readtimeout);
// Add time for timeout value
readtimeout.tv_sec += rlocktime.tv_sec;
readtimeout.tv_nsec += rlocktime.tv_nsec;
int rc = pthread_rwlock_timedrdlock(&rwlock, &readtimeout);
if (rc) {
if (rc == ETIMEDOUT) {
fprintf(stderr, "=== READ LOCK CANCEL POINT == TID=%llu OBJECT=%llx\n",
(unsigned long long) XrdSysThread::ID(), (unsigned long long) this);
XrdSysThread::SetCancelOn();
XrdSysThread::CancelPoint();
XrdSysTimer msSleep;
msSleep.Wait(100);
XrdSysThread::SetCancelOff();
} else {
fprintf(stderr, "=== READ LOCK EXCEPTION == TID=%llu OBJECT=%llx rc=%d\n",
(unsigned long long) XrdSysThread::ID(), (unsigned long long) this, rc);
std::terminate();
}
} else {
break;
}
}
#else
LockRead();
#endif
EOS_RWMUTEX_TIMER_STOP_AND_UPDATE(mRd);
}
//------------------------------------------------------------------------------
// Unlock a read lock
......@@ -516,7 +463,7 @@ PthreadRWMutex::UnLockWrite()
// Lock for write but give up after wlocktime
//------------------------------------------------------------------------------
int
PthreadRWMutex::TimeoutLockWrite()
PthreadRWMutex::TimedWrLock(uint64_t timeout_ns)
{
EOS_RWMUTEX_CHECKORDER_LOCK;
int retc = 0;
......@@ -531,10 +478,21 @@ PthreadRWMutex::TimeoutLockWrite()
}
#endif
struct timespec timeout = {0};
_clock_gettime(CLOCK_REALTIME, &timeout);
if (timeout_ns) {
if (timeout_ns > 1e9) {
timeout.tv_sec += (timeout_ns / 1e9);
}
timeout.tv_nsec += (timeout_ns % (unsigned long long) 1e9);
}
#ifdef __APPLE__
retc = pthread_rwlock_wrlock(&rwlock);
#else
retc = pthread_rwlock_timedwrlock(&rwlock, &wlocktime);
retc = pthread_rwlock_timedwrlock(&rwlock, &timeout);
#endif
#ifdef EOS_INSTRUMENTED_RWMUTEX
......
......@@ -109,27 +109,23 @@ public:
}
//----------------------------------------------------------------------------
//! Set the time to wait for the acquisition of the write mutex before
//! releasing quicky and retrying.
//!
//! @param nsec nanoseconds
//----------------------------------------------------------------------------
void SetWLockTime(const size_t& nsec) override;
//----------------------------------------------------------------------------
//! Lock for read
//----------------------------------------------------------------------------
void LockRead() override;
//----------------------------------------------------------------------------
//! Lock for read allowing to be canceled waiting for the lock
//! Unlock a read lock
//----------------------------------------------------------------------------
void LockReadCancel() override;
void UnLockRead() override;
//----------------------------------------------------------------------------
//! Unlock a read lock
//! Try to read lock the mutex within the timeout
//!
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
void UnLockRead() override;
int TimedRdLock(uint64_t timeout_ns) override;
//----------------------------------------------------------------------------
//! Lock for write
......@@ -142,28 +138,23 @@ public:
void UnLockWrite() override;
//----------------------------------------------------------------------------
//! Try to read lock the mutex within the timout value
//! Try to write lock the mutex within the timeout
//!
//! @param timeout_ms time duration in milliseconds we can wait for the lock
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if lock aquired, ETIMEOUT if timeout occured
//----------------------------------------------------------------------------
int TimedRdLock(uint64_t timeout_ms) override;
//----------------------------------------------------------------------------
//! Lock for write but give up after wlocktime
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
int TimeoutLockWrite() override;
int TimedWrLock(uint64_t timeout_ns) override;
//----------------------------------------------------------------------------
//! Get Readlock Counter
//----------------------------------------------------------------------------
size_t GetReadLockCounter() override;
uint64_t GetReadLockCounter() override;
//----------------------------------------------------------------------------
//! Get Writelock Counter
//----------------------------------------------------------------------------
size_t GetWriteLockCounter() override;
uint64_t GetWriteLockCounter() override;
#ifdef EOS_INSTRUMENTED_RWMUTEX
......@@ -449,9 +440,8 @@ private:
pthread_rwlock_t rwlock;
pthread_rwlockattr_t attr;
struct timespec wlocktime;
struct timespec rlocktime;
size_t mRdLockCounter;
size_t mWrLockCounter;
uint64_t mRdLockCounter;
uint64_t mWrLockCounter;
bool mPreferRd; ///< If true reads go ahead of wr and are reentrant
#ifdef EOS_INSTRUMENTED_RWMUTEX
......
......@@ -81,14 +81,10 @@ RWMutexWriteLock::~RWMutexWriteLock()
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
RWMutexReadLock::RWMutexReadLock(RWMutex& mutex, bool allow_cancel):
RWMutexReadLock::RWMutexReadLock(RWMutex& mutex):
mRdMutex(&mutex)
{
if (allow_cancel) {
mRdMutex->LockReadCancel();
} else {
mRdMutex->LockRead();
}
mRdMutex->LockRead();
}
//----------------------------------------------------------------------------
......
......@@ -66,17 +66,6 @@ public:
}
//----------------------------------------------------------------------------
//! Set the time to wait for the acquisition of the write mutex before
//! releasing quicky and retrying.
//!
//! @param nsec nanoseconds
//----------------------------------------------------------------------------
void SetWLockTime(const size_t& nsec)
{
mMutexImpl->SetWLockTime(nsec);
}
//----------------------------------------------------------------------------
//! Lock for read
//----------------------------------------------------------------------------
void LockRead()
......@@ -85,11 +74,15 @@ public:
}
//----------------------------------------------------------------------------
//! Lock for read allowing to be canceled waiting for the lock
//! Try to read lock the mutex within the timeout
//!
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
void LockReadCancel()
int TimedRdLock(uint64_t timeout_ns)
{
mMutexImpl->LockReadCancel();
return mMutexImpl->TimedRdLock(timeout_ns);
}
//----------------------------------------------------------------------------
......@@ -117,29 +110,21 @@ public:
}
//----------------------------------------------------------------------------
//! Try to read lock the mutex within the timout value
//! Try to write lock the mutex within the timeout
//!
//! @param timeout_ms time duration in milliseconds we can wait for the lock
//! @param timeout_ns nano seconds timeout
//!
//! @return 0 if lock aquired, ETIMEOUT if timeout occured
//----------------------------------------------------------------------------
int TimedRdLock(uint64_t timeout_ms)
{
return mMutexImpl->TimedRdLock(timeout_ms);
}
//----------------------------------------------------------------------------
//! Lock for write but give up after wlocktime
//! @return 0 if succcessful, otherwise error code
//----------------------------------------------------------------------------
int TimeoutLockWrite()
int TimedWrLock(uint64_t timeout_ns)
{
return mMutexImpl->TimeoutLockWrite();
return mMutexImpl->TimedWrLock(timeout_ns);
}
//----------------------------------------------------------------------------
//! Get read lock counter
//----------------------------------------------------------------------------
size_t GetReadLockCounter()
uint64_t GetReadLockCounter()
{
return mMutexImpl->GetReadLockCounter();
}
......@@ -147,7 +132,7 @@ public:
//----------------------------------------------------------------------------
//! Get write lock counter
//----------------------------------------------------------------------------
size_t GetWriteLockCounter()
uint64_t GetWriteLockCounter()
{
return mMutexImpl->GetWriteLockCounter();
}
......@@ -212,9 +197,8 @@ public:
//! Constructor
//!
//! @param mutex mutex to handle
//! @param allow_cancel allow cancelling if true
//----------------------------------------------------------------------------
RWMutexReadLock(RWMutex& mutex, bool allow_cancel = false);
RWMutexReadLock(RWMutex& mutex);
//----------------------------------------------------------------------------
//! Grab mutex and read lock it
......
......@@ -117,8 +117,9 @@ xrdmgmofs_shutdown(int sig)
}
eos_static_warning("Shutdown:: grab write mutex");
uint64_t timeout_ns = 3 * 1e9;
while (gOFS->eosViewRWMutex.TimeoutLockWrite()) {
while (gOFS->eosViewRWMutex.TimedWrLock(timeout_ns)) {
eos_static_warning("Trying to get the wr lock on eosViewRWMutex");
}
......@@ -153,7 +154,7 @@ xrdmgmofs_shutdown(int sig)
delete gOFS->eosContainerAccounting;
}
while (gOFS->eosViewRWMutex.TimeoutLockWrite()) {
while (gOFS->eosViewRWMutex.TimedWrLock(timeout_ns)) {
eos_static_warning("Trying to get the wr lock on eosViewRWMutex");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment