Obtain a write lock on a resource. This will spin until either the lock is granted or the lock is deactivated (host entity destructed). And then spin until the read count falls to zero. This latter step ensures no thread can read the resource during a write.
| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzLockRWD::LockWrite | (int32_t,) |
Declared in file: hzLock.h
Defined in file : hzLock.cpp
Function Logic:
Function body:
hzEcode hzLockRWD::LockWrite (int32_t timeout)
{
// Obtain a write lock on a resource. This will spin until either the lock is granted or the lock is deactivated (host entity destructed). And
// then spin until the read count falls to zero. This latter step ensures no thread can read the resource during a write.
//
// Arguments: 1) timout The limit of retries (in thousands)
//
// Returns: E_NOTFOUND The previous thread with write access killed the lock (should be because it deleted the applicable resource)
// E_TIMEOUT The thread holding write access has held the lock for too long
// E_OK Write access granted
_hzfunc("hzLockRWD::LockWrite") ;
uint64_t now ; // Time lock sought
uint64_t got ; // Time lock granted
uint32_t cont ; // Contention or spin count
uint32_t tries ; // Contention or spin count
uint32_t tid ; // Thread id
uint32_t limit ; // Timeout as number of tries
if (!_hzGlobal_MT)
return E_OK ;
now = RealtimeNano() ;
tid = pthread_self() ;
limit = timeout < 0? 0xfffffffe:timeout*1000;
if (m_lockval == tid)
{
m_recurse++ ;
// m_SpinLocksR++ ;
m_LockOpsW++ ;
m_SpinsThis = 0;
return E_OK ;
}
for (tries = cont = 0;;)
{
if (m_lockval)
{
cont++ ;
continue ;
}
if (!__sync_val_compare_and_swap(&(m_lockval), 0,tid))
{
if (m_lockval == tid)
break ;
}
tries++ ;
if (tries > limit)
return E_TIMEOUT ;
}
// Wait for counter to drop to zero
for (; m_counter ; cont++) ;
// Note: Can only set m_lockval when we have the lock
m_lockval = tid ;
m_recurse = 0;
// m_SpinLocksP++ ;
m_LockOpsW++ ;
m_TriesThis = tries ;
m_TriesTotal += tries ;
m_SpinsThis = cont ;
m_SpinsTotal += cont ;
got = RealtimeNano() ;
m_Granted = got ;
m_WaitThis = (got - now) ;
m_WaitTotal += m_WaitThis ;
return E_OK ;
}