CXSpinLock

From cxwiki

The CXSpinLock class offers similar capabilities to CXMutex but with different performance tradeoffs. The object exists in one of two states: LOCKED or UNLOCKED. Any thread may lock the object, after which any further attempt (by any thread, including the lock-owner) to lock it again will block until it has been unlocked. The unlock must be performed by the lock-owner thread.

// Lock the mutex to the current thread. Blocks while any thread still has the mutex locked.
void LockMutex(void) const; 

// Unlocks the mutex from the current thread.
void UnlockMutex(void) const;

// Attempts to lock the mutex, but does not block. Returns true if a lock was successfully taken.
bool TryAndLockMutex(void) const;

Restrictions

  • The CXSpinLock is UNLOCKED when constructed. 
  • The CXSpinLock should be returned to the UNLOCKED state prior to destruction. It is considered an error for the application to destroy a CXSpinLock while it is locked, because that would likely to lead to unlock attempts after destruction. 
  • An attempt to lock or unlock a CXSpinLock during or after its destruction is considered an error. The resultant behaviour is undefined. This includes the scenario where a lock attempt is placed prior to destruction, but cannot be honored until destruction has begun. 
  • It is considered an error for the application to attempt to lock a CXSpinLock on the lock-owner thread. The resultant behaviour is undefined, typically leading to either a deadlock, an assertion, or both. 
  • No attempt is made to detect or recover from deadlocks. It is the callers responsibility to ensure that locks are taken and released in an approriate manner to avoid deadlocks. 
  • It is considered an error to attempt to unlock a mutex on a thread which is no the lock-owner. 

Performance

CXSpinLock typically uses the underlying OS spin-lock support, which typically avoids performing a system call. This means that it is measurably faster than CXMutex in cases where the lock is not contested. If the lock is contested, CXSpinLock will spin for a short period, with the hope that the lock-owner thread will complete its work quickly and release the lock. This trades off CPU efficiency during the wait (the CPU time spent wasting is simply wasted) against the CPU efficiency of making a system call (which is wasted in the event that the lock is not contested, and may be heavier than a busy-wait for contested locks which unlock quickly). In the worst-case scenario, the lock-owner thread may hold the lock for an extended period, causing CXSpinLock to consume substantial CPU resources for no benefit. Most implementations will fall back to a system call after a short timeout to avoid substantial performance losses. As a result, CXSpinLock is well-suited to tasks where locking and unlocking do occur very frequently, and where the amount of time spent with the lock held is trivial.

CXSpinLock provides no guarantees of mutex fairness.