using System.Collections; using System.Collections.Generic; using System.Threading; using System; namespace ProcessHacker.Common.Threading { public class FastStack : IEnumerable { private class FastStackNode { public U Value; public FastStackNode Next; } private int _count = 0; private FastStackNode _bottom = null; public int Count { get { return _count; } } public T Peek() { FastStackNode bottom; bottom = _bottom; if (bottom == null) throw new InvalidOperationException("The stack is empty."); return bottom.Value; } public T Pop() { FastStackNode bottom; // Atomically replace the bottom of the stack. while (true) { bottom = _bottom; // If the bottom of the stack is null, the // stack is empty. if (bottom == null) throw new InvalidOperationException("The stack is empty."); // Try to replace the pointer. if (Interlocked.CompareExchange>( ref _bottom, bottom.Next, bottom ) == bottom) { // Success. return bottom.Value; } } } public void Push(T value) { FastStackNode bottom; FastStackNode entry; entry = new FastStackNode(); entry.Value = value; // Atomically replace the bottom of the stack. while (true) { bottom = _bottom; entry.Next = bottom; // Try to replace the pointer. if (Interlocked.CompareExchange>( ref _bottom, entry, bottom ) == bottom) { // Success. break; } } } public IEnumerator GetEnumerator() { FastStackNode entry; entry = _bottom; // Start the enumeration. while (entry != null) { yield return entry.Value; entry = entry.Next; } } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } }