/// <summary> /// Called when [timer callback]. /// </summary> /// <param name="currTime">The curr time.</param> internal void OnTimerCallback(long currTime) { if (!SlimLock.Enter(0)) { return; } try { while (true) { currTime = PerformanceObserver.MicroTime; if (currTime < NextTime) { break; } NextTime += Interval; var callback = TimerCallback; if (callback != null) { callback.Invoke(null); } } } finally { SlimLock.Release(); } }
public void ShouldEnterAndLeaveInSingleThread() { var @lock = new SlimLock(); @lock.Enter(); @lock.Leave(); }
public void ShouldFailForDoubleLeave() { var @lock = new SlimLock(); @lock.Enter(); @lock.Leave(); Assert.Catch <Exception>(() => @lock.Leave(), "Enter/Leave should have balance"); }
private T SetValue(T value, int thread) { // Setting values causes the _hashIndex to become unstable ... we // should probably avoid chaining if at all possible too so that the // only element in the hash index is the element itself ... var nodeTable = _nodeTable; var hashIndex = _hashIndex; // Look for the node in the current space var hashCode = thread & 0x7fffffff; // Get the appropriate node index - remember there are no direct node references var chainIndex = hashIndex[hashCode % hashIndex.Length]; // Skip entries that do not share the same hashcode if (chainIndex != -1) { if (nodeTable[chainIndex].HashCode == hashCode) { if (nodeTable[chainIndex].ThreadId == thread) { nodeTable[chainIndex].Value = value; return(value); } } } _wLock.Enter(); try { // Allocate a node var nodeIndex = AllocNode(thread, value, hashCode); // MapIndex the node while (true) { hashIndex = _hashIndex; chainIndex = hashCode % hashIndex.Length; if (hashIndex[chainIndex] == -1) { hashIndex[chainIndex] = nodeIndex; return(value); } ReIndex(); } } finally { _wLock.Release(); } }