SXMutex Class Reference

An SXMutex implements a standard readers/writers exclusion scheme: any number of shared-lock threads may hold the lock at one time, during which time exclusive-lock threads are blocked; only one exclusive-lock thread may hold the lock at a time, during which all other lock-requesting threads are blocked. More...

#include <SXMutex.h>

Inheritance diagram for SXMutex:

SynchMonitoredObject List of all members.

Public Types

enum  SchedulingPolicy { SCHEDULE_DEFAULT, SCHEDULE_FAVOR_EXCLUSIVE }
 Enumeration of available scheduling policies. More...

Public Member Functions

 SXMutex ()
 ~SXMutex ()
bool waitFor (LockMode lockMode, uint iTimeout=ETERNITY, TxnId txnId=IMPLICIT_TXN_ID)
void release (LockMode lockMode, TxnId txnId=IMPLICIT_TXN_ID)
bool tryUpgrade (TxnId txnId=IMPLICIT_TXN_ID)
bool isLocked (LockMode lockdMode) const
void setSchedulingPolicy (SchedulingPolicy schedulingPolicy)

Protected Attributes

StrictMutex mutex
LocalCondition condition

Private Attributes

SchedulingPolicy schedulingPolicy
uint nShared
uint nExclusive
uint nExclusivePending
LockHolderId exclusiveHolderId

Detailed Description

An SXMutex implements a standard readers/writers exclusion scheme: any number of shared-lock threads may hold the lock at one time, during which time exclusive-lock threads are blocked; only one exclusive-lock thread may hold the lock at a time, during which all other lock-requesting threads are blocked.

Note on nomenclature: RWLock is a more standard name. However, this synchronization object is used in places where there's not a direct correlation between shared/read and exclusive/write. (For example, for a checkpoint lock, writer threads take a shared lock and the checkpointing thread takes an exclusive lock). And "mutex" is more specific than "lock", which is used in boost in the sense of a guard.

Definition at line 53 of file SXMutex.h.


Member Enumeration Documentation

enum SXMutex::SchedulingPolicy

Enumeration of available scheduling policies.

Enumerator:
SCHEDULE_DEFAULT  Scheduling is determined by the OS with no preferences given.

This may lead to starvation of exclusive lock requests.

SCHEDULE_FAVOR_EXCLUSIVE  Exclusive locks are always favored, so once a thread is waiting for an exclusive lock, no new shared locks can be obtained.

This may lead to starvation of shared lock requests. Deadlock is also a danger if multiple shared locks are requested by the same thread, since an exclusive request may begin after the first request is granted, blocking the second request.

Definition at line 59 of file SXMutex.h.

00060     {
00065         SCHEDULE_DEFAULT,
00066 
00075         SCHEDULE_FAVOR_EXCLUSIVE
00076     };


Constructor & Destructor Documentation

SXMutex::SXMutex (  )  [explicit]

Definition at line 29 of file SXMutex.cpp.

References nExclusive, nExclusivePending, nShared, SCHEDULE_DEFAULT, and schedulingPolicy.

00030 {
00031     nShared = 0;
00032     nExclusive = 0;
00033     nExclusivePending = 0;
00034     schedulingPolicy = SCHEDULE_DEFAULT;
00035 }

SXMutex::~SXMutex (  ) 

Definition at line 37 of file SXMutex.cpp.

References exclusiveHolderId, LockHolderId::isNull(), nExclusive, nExclusivePending, and nShared.

00038 {
00039     assert(!nShared);
00040     assert(!nExclusive);
00041     assert(!nExclusivePending);
00042     assert(exclusiveHolderId.isNull());
00043 }


Member Function Documentation

bool SXMutex::waitFor ( LockMode  lockMode,
uint  iTimeout = ETERNITY,
TxnId  txnId = IMPLICIT_TXN_ID 
)

Definition at line 52 of file SXMutex.cpp.

References SynchMonitoredObject::condition, convertTimeout(), ETERNITY, exclusiveHolderId, LOCKMODE_S_NOWAIT, LOCKMODE_X, LOCKMODE_X_NOWAIT, SynchMonitoredObject::mutex, nExclusive, nExclusivePending, nShared, SCHEDULE_FAVOR_EXCLUSIVE, and schedulingPolicy.

Referenced by SXMutexGuard< lockMode >::lock().

00053 {
00054     boost::xtime atv;
00055     if (iTimeout != ETERNITY) {
00056         convertTimeout(iTimeout,atv);
00057     }
00058     StrictMutexGuard mutexGuard(mutex);
00059     LockHolderId acquirerId(txnId);
00060     bool bExclusive = (lockMode == LOCKMODE_X || lockMode == LOCKMODE_X_NOWAIT);
00061     bool bExclusivePending = (lockMode == LOCKMODE_X)
00062         && (schedulingPolicy == SCHEDULE_FAVOR_EXCLUSIVE);
00063     if (bExclusivePending) {
00064         ++nExclusivePending;
00065     }
00066     for (;;) {
00067         if (exclusiveHolderId == acquirerId) {
00068             break;
00069         }
00070         if (bExclusive) {
00071             if (!nExclusive && !nShared) {
00072                 break;
00073             }
00074         } else {
00075             if (!nExclusive && !nExclusivePending) {
00076                 break;
00077             }
00078         }
00079         if (lockMode >= LOCKMODE_S_NOWAIT) {
00080             // NOTE:  for LOCKMODE_X_NOWAIT, don't need to decrement
00081             // nExclusivePending since we didn't bother incrementing it
00082             return false;
00083         }
00084         if (iTimeout == ETERNITY) {
00085             condition.wait(mutexGuard);
00086         } else {
00087             if (!condition.timed_wait(mutexGuard,atv)) {
00088                 if (bExclusivePending) {
00089                     assert(nExclusivePending > 0);
00090                     --nExclusivePending;
00091                 }
00092                 return false;
00093             }
00094         }
00095     }
00096     if (bExclusive) {
00097         ++nExclusive;
00098         exclusiveHolderId = acquirerId;
00099         if (bExclusivePending) {
00100             assert(nExclusivePending > 0);
00101             --nExclusivePending;
00102         }
00103     } else {
00104         ++nShared;
00105     }
00106     return true;
00107 }

void SXMutex::release ( LockMode  lockMode,
TxnId  txnId = IMPLICIT_TXN_ID 
)

Definition at line 109 of file SXMutex.cpp.

References SynchMonitoredObject::condition, exclusiveHolderId, LOCKMODE_S, LOCKMODE_X, SynchMonitoredObject::mutex, nExclusive, nShared, and LockHolderId::setNull().

Referenced by SXMutexGuard< lockMode >::unlock().

00110 {
00111     StrictMutexGuard mutexGuard(mutex);
00112     if (lockMode == LOCKMODE_X) {
00113         assert(nExclusive);
00114         LockHolderId releaserId(txnId);
00115         assert(exclusiveHolderId == releaserId);
00116         --nExclusive;
00117         if (!nExclusive) {
00118             exclusiveHolderId.setNull();
00119             condition.notify_all();
00120         }
00121     } else {
00122         assert(lockMode == LOCKMODE_S);
00123         assert(nShared);
00124         // NOTE:  we can't assert(exclusiveHolderId.isNull()) here,
00125         // because a txn may take both a shared lock and an exclusive
00126         // lock simultaneously.
00127         --nShared;
00128         if (!nShared) {
00129             condition.notify_all();
00130         }
00131     }
00132 }

bool SXMutex::tryUpgrade ( TxnId  txnId = IMPLICIT_TXN_ID  ) 

Definition at line 144 of file SXMutex.cpp.

References exclusiveHolderId, LockHolderId::isNull(), SynchMonitoredObject::mutex, nExclusive, and nShared.

00145 {
00146     StrictMutexGuard mutexGuard(mutex);
00147     assert(nShared);
00148     assert(!nExclusive);
00149     assert(exclusiveHolderId.isNull());
00150     if (nShared > 1) {
00151         return false;
00152     }
00153     // otherwise assume caller holds the unique shared lock, and ignore
00154     // nExclusivePending
00155     nShared = 0;
00156     nExclusive = 1;
00157     LockHolderId holderId(txnId);
00158     exclusiveHolderId = holderId;
00159     return true;
00160 }

bool SXMutex::isLocked ( LockMode  lockdMode  )  const

Definition at line 134 of file SXMutex.cpp.

References LOCKMODE_S, LOCKMODE_X, nExclusive, and nShared.

Referenced by VersionedRandomAllocationSegment::deallocateSinglePage(), VersionedRandomAllocationSegment::findAllocPageIdForRead(), VersionedRandomAllocationSegment::freeTempPage(), SnapshotRandomAllocationSegment::incrPageUpdateCount(), TwoQVictimPolicy< PageT >::notifyPopularPageAccess(), VersionedRandomAllocationSegment::uncommittedDeallocation(), VersionedRandomAllocationSegment::updateExtentEntry(), VersionedRandomAllocationSegment::updatePageEntry(), and VersionedRandomAllocationSegment::updateTempPageEntry().

00135 {
00136     if (lockMode == LOCKMODE_X) {
00137         return nExclusive ? true : false;
00138     } else {
00139         assert(lockMode == LOCKMODE_S);
00140         return nShared ? true : false;
00141     }
00142 }

void SXMutex::setSchedulingPolicy ( SchedulingPolicy  schedulingPolicy  ) 

Definition at line 45 of file SXMutex.cpp.

References SynchMonitoredObject::mutex, nExclusive, nExclusivePending, nShared, and schedulingPolicy.

Referenced by CheckpointThread::CheckpointThread(), and PagingTestBase::PagingTestBase().

00046 {
00047     StrictMutexGuard mutexGuard(mutex);
00048     assert(!nShared && !nExclusive && !nExclusivePending);
00049     schedulingPolicy = schedulingPolicyInit;
00050 }


Member Data Documentation

SchedulingPolicy SXMutex::schedulingPolicy [private]

Definition at line 91 of file SXMutex.h.

Referenced by setSchedulingPolicy(), SXMutex(), and waitFor().

uint SXMutex::nShared [private]

Definition at line 92 of file SXMutex.h.

Referenced by isLocked(), release(), setSchedulingPolicy(), SXMutex(), tryUpgrade(), waitFor(), and ~SXMutex().

uint SXMutex::nExclusive [private]

Definition at line 92 of file SXMutex.h.

Referenced by isLocked(), release(), setSchedulingPolicy(), SXMutex(), tryUpgrade(), waitFor(), and ~SXMutex().

uint SXMutex::nExclusivePending [private]

Definition at line 92 of file SXMutex.h.

Referenced by setSchedulingPolicy(), SXMutex(), waitFor(), and ~SXMutex().

LockHolderId SXMutex::exclusiveHolderId [private]

Definition at line 93 of file SXMutex.h.

Referenced by release(), tryUpgrade(), waitFor(), and ~SXMutex().

StrictMutex SynchMonitoredObject::mutex [protected, inherited]

Definition at line 38 of file SynchMonitoredObject.h.

Referenced by ParallelExecStreamScheduler::abort(), LogicalTxnLog::checkpoint(), Database::checkpointImpl(), CheckpointThread::closeImpl(), LogicalTxnLog::commitTxn(), ParallelExecStreamScheduler::executeManager(), ParallelExecStreamScheduler::executeTask(), LogicalTxnLog::getOldestActiveTxnId(), LogicalTxnLog::newLogicalTxn(), ParallelExecStreamScheduler::readStream(), release(), GroupLock::release(), Database::requestCheckpoint(), CheckpointThread::requestCheckpoint(), LogicalTxnLog::rollbackTxn(), TimerThread::run(), CheckpointThread::run(), ThreadPoolBase::runPooledThread(), setSchedulingPolicy(), TimerThread::signalImmediate(), ParallelExecStreamScheduler::signalSentinel(), ThreadPoolBase::start(), TimerThread::stop(), ThreadPoolBase::stop(), ParallelExecStreamScheduler::stop(), ThreadPool< RandomAccessRequest >::submitTask(), ParallelExecStreamScheduler::tryExecuteManager(), ParallelExecStreamScheduler::tryExecuteTask(), tryUpgrade(), waitFor(), GroupLock::waitFor(), and Database::writeStats().

LocalCondition SynchMonitoredObject::condition [protected, inherited]

Definition at line 39 of file SynchMonitoredObject.h.

Referenced by ParallelExecStreamScheduler::abort(), Database::checkpointImpl(), CheckpointThread::closeImpl(), LogicalTxnLog::commitTxnWithGroup(), ParallelExecStreamScheduler::executeTask(), ParallelExecStreamScheduler::readStream(), release(), GroupLock::release(), Database::requestCheckpoint(), CheckpointThread::requestCheckpoint(), TimerThread::run(), CheckpointThread::run(), ThreadPoolBase::runPooledThread(), TimerThread::signalImmediate(), TimerThread::stop(), ThreadPoolBase::stop(), ParallelExecStreamScheduler::stop(), ThreadPool< RandomAccessRequest >::submitTask(), ParallelExecStreamScheduler::tryExecuteManager(), ParallelExecStreamScheduler::tryExecuteTask(), waitFor(), and GroupLock::waitFor().


The documentation for this class was generated from the following files:
Generated on Mon Jun 22 04:00:47 2009 for Fennel by  doxygen 1.5.1