public void Lock() { int myCluster = ThreadID.GetCluster(); Backoff localBackoff = new Backoff(LOCAL_MIN_DELAY, LOCAL_MAX_DELAY); Backoff remoteBackoff = new Backoff(REMOTE_MIN_DELAY, REMOTE_MAX_DELAY); while (true) { if (Interlocked.CompareExchange(ref state, myCluster, FREE) == FREE) { return; } int lockState = state; if (lockState == myCluster) { localBackoff.DoBackoff(); } else { remoteBackoff.DoBackoff(); } } }
public void NodeUnlock() { int oldState = 0; int newState = (int)ThreadID.GetCluster(); // successorMustWait = true; newState |= SMW_MASK; // tailWhenSpliced = false; newState &= (~TWS_MASK); do { oldState = state; } while (Interlocked.CompareExchange(ref state, oldState, newState) != oldState); }
public void Lock() { QNode myNode = currNode.Value; QNode localQueue = localQueues[ThreadID.GetCluster()]; // splice my QNode into local queue QNode myPred = null; do { myPred = localQueue; } while (Interlocked.CompareExchange(ref localQueue, myPred, myNode) != myNode); if (myPred != null) { bool iOwnLock = myPred.WaitForGrantOrClusterMaster(); if (iOwnLock) { predNode.Value = myPred; return; } } // I am the cluster master: splice local queue into global queue. QNode localTail = null; do { myPred = globalQueue; localTail = localQueue; } while (Interlocked.CompareExchange(ref globalQueue, myPred, localTail) != localTail); // inform successor it is the new master localTail.TailWhenSpliced = true; while (myPred.SuccessorMustWait) { } ; predNode.Value = myPred; return; }