/// <summary> /// Acquires the reader lock. /// </summary> /// <param name="timeout">The timeout.</param> public void AcquireReaderLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var ii = 0; for (;;) { var result = WithMainLock( timeCur, timeEnd, () => { if ((_uLockFlags == LockFlags.None) || (_uLockFlags == LockFlags.Shared)) { _uSharedCount++; return(true); } return(false); }); if (result) { return; } SlimLock.SmartWait(++ii); timeCur = DateTimeHelper.CurrentTimeMillis; } }
/// <summary> /// Initializes a new instance of the <see cref="MonitorSlimLock"/> class. /// </summary> public MonitorSlimLock(int lockTimeout) { _uLockId = Guid.NewGuid(); _uLockObj = new SlimLock(); _uLockDepth = 0; _uLockTimeout = lockTimeout; }
/// <summary> /// Acquires the writer lock. /// </summary> /// <param name="timeout">The timeout.</param> public void AcquireWriterLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var ii = 0; var upgrade = new bool[] { false }; try { for (;;) { var result = WithMainLock( timeCur, timeEnd, () => { if (_uLockFlags == LockFlags.None) { _uLockFlags = LockFlags.Exclusive; _uLockOwner = System.Threading.Thread.CurrentThread.ManagedThreadId; return(true); } else if (_uLockFlags == LockFlags.Shared) { _uLockFlags |= LockFlags.ExclusiveUpgrade; upgrade[0] = true; return(false); } else if (_uLockFlags == LockFlags.ExclusiveUpgrade) { // shared flag has been cleared upgrade[0] = false; _uLockFlags = LockFlags.Exclusive; _uLockOwner = System.Threading.Thread.CurrentThread.ManagedThreadId; return(true); } // Exclusive - wait return(false); }); if (result) { return; } SlimLock.SmartWait(++ii); timeCur = DateTimeHelper.CurrentTimeMillis; } } finally { if (upgrade[0]) { WithMainLock(() => _uLockFlags &= ~LockFlags.ExclusiveUpgrade); } } }
/// <summary> /// Waits for the latch to be released for up to the specified amount of time. /// If the timeout expires a TimeoutException is thrown. /// </summary> /// <param name="timeout">The timeout.</param> /// <returns></returns> public bool Await(TimeSpan timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + (long)timeout.TotalMilliseconds; var iteration = 0; while (Interlocked.Read(ref _latchCount) > 0) { if (!SlimLock.SmartWait(++iteration, timeEnd)) { return(false); } } return(true); }
/// <summary> /// Acquires the reader lock. /// </summary> /// <param name="timeout">The timeout.</param> public Node AcquireReaderLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var curr = _rnode; var node = PushNode(new Node(NodeFlags.Shared)); var iter = 0; for ( ;;) { #if STATISTICS node.Iterations++; #endif if (curr == node) { #if STATISTICS node.TimeAcquire = PerformanceObserver.MicroTime; #endif return(_rnode = node); } else if (curr.Flags == NodeFlags.Shared) { curr = curr.Next; #if STATISTICS node.ChainLength++; #endif } else if (curr.Flags == NodeFlags.Exclusive) { SlimLock.SmartWait(++iter); } else if (curr.Flags == NodeFlags.None) { curr = curr.Next; // dead node #if STATISTICS node.ChainLength++; #endif } else { throw new IllegalStateException(); } } }
/// <summary> /// Initializes a new instance of the <see cref="XperThreadLocal{T}"/> class. /// </summary> /// <param name="factory">The factory.</param> public XperThreadLocal(FactoryDelegate <T> factory) { _primeIndex = 0; var tableSize = Prime.HashPrimes[_primeIndex]; _hashIndex = new int[tableSize]; for (int ii = 0; ii < tableSize; ii++) { _hashIndex[ii] = -1; } _nodeTable = new Node[tableSize]; _valueFactory = factory; _wLock = new SlimLock(); }
/// <summary> /// Gets the value. If a value is not available before the timeout expires, /// a TimeoutException will be thrown. /// </summary> /// <param name="timeOut">The time out.</param> /// <returns></returns> public T GetValue(TimeSpan timeOut) { var timeCur = PerformanceObserver.MilliTime; var timeEnd = timeCur + timeOut.TotalMilliseconds; for (int ii = 0; !_hasValue; ii++) { timeCur = PerformanceObserver.MilliTime; if (timeCur > timeEnd) { throw new TimeoutException(); } SlimLock.SmartWait(ii); } return(Value); }
/// <summary> /// Initializes a new instance of the <see cref="SlimThreadLocal{T}"/> class. /// </summary> /// <param name="factory">The factory.</param> public SlimThreadLocal(Func <T> factory) { _threadTable = new Dictionary <Thread, T>(new ThreadEq()); _valueFactory = factory; _wLock = new SlimLock(); }