mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
added some lock-free structures
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1719 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -76,13 +76,8 @@ FORCEINLINE VOID KphAcquireBitSpinLock(
|
||||
__in LONG Bit
|
||||
)
|
||||
{
|
||||
/* Fast path - try to acquire the lock outside of the loop first. */
|
||||
if (InterlockedBitTestAndSet(Value, Bit))
|
||||
{
|
||||
/* Slow path - lock was already acquired by someone else; spin. */
|
||||
while (InterlockedBitTestAndSet(Value, Bit))
|
||||
YieldProcessor();
|
||||
}
|
||||
while (InterlockedBitTestAndSet(Value, Bit))
|
||||
YieldProcessor();
|
||||
}
|
||||
|
||||
/* KphReleaseBitSpinLock
|
||||
|
||||
@@ -30,11 +30,11 @@ namespace ProcessHacker.Common
|
||||
public class FreeList<T>
|
||||
where T : IResettable, new()
|
||||
{
|
||||
private class FreeListEntry<T>
|
||||
where T : IResettable, new()
|
||||
private class FreeListEntry<U>
|
||||
where U : IResettable, new()
|
||||
{
|
||||
public T Object;
|
||||
public FreeListEntry<T> Next;
|
||||
public U Object;
|
||||
public FreeListEntry<U> Next;
|
||||
}
|
||||
|
||||
private FreeListEntry<T> _listHead = null;
|
||||
|
||||
@@ -70,9 +70,11 @@
|
||||
<Compile Include="IResettable.cs" />
|
||||
<Compile Include="Logging.cs" />
|
||||
<Compile Include="Messaging\MessageQueue.cs" />
|
||||
<Compile Include="Threading\FastQueue.cs" />
|
||||
<Compile Include="Threading\RundownProtection.cs" />
|
||||
<Compile Include="Threading\SemaphorePair.cs" />
|
||||
<Compile Include="Threading\SpinLock.cs" />
|
||||
<Compile Include="Threading\FastStack.cs" />
|
||||
<Compile Include="Threading\WaitableQueue.cs" />
|
||||
<Compile Include="Tokenizer.cs" />
|
||||
<Compile Include="Ui\SortedListViewComparer.cs" />
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ProcessHacker.Common.Threading
|
||||
{
|
||||
public class FastQueue<T> : IEnumerable<T>
|
||||
{
|
||||
private class FastQueueNode<U>
|
||||
{
|
||||
public U Value;
|
||||
public FastQueueNode<U> Next;
|
||||
}
|
||||
|
||||
private int _count = 0;
|
||||
// The head node. The next pointer of the head node always points
|
||||
// to the least recently added node - the node to dequeue first.
|
||||
private FastQueueNode<T> _head;
|
||||
// The tail node. This is always the most recently added node.
|
||||
private FastQueueNode<T> _tail;
|
||||
// Note: all next pointers point to less recently added nodes (i.e.
|
||||
// the next node to dequeue).
|
||||
|
||||
public FastQueue()
|
||||
{
|
||||
_head = new FastQueueNode<T>();
|
||||
_tail = _head;
|
||||
_tail.Next = null;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
}
|
||||
|
||||
public T Dequeue()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Enqueue(T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
FastQueueNode<T> tail;
|
||||
FastQueueNode<T> tailNext;
|
||||
FastQueueNode<T> node;
|
||||
|
||||
// Create a new queue node.
|
||||
node = new FastQueueNode<T>();
|
||||
node.Value = value;
|
||||
node.Next = null;
|
||||
|
||||
// Add the node to the tail of the list, atomically.
|
||||
// We have to set the next pointer of the current tail node
|
||||
// and then replace the tail pointer with our new node.
|
||||
while (true)
|
||||
{
|
||||
tailNext = _tail.Next;
|
||||
|
||||
while (true)
|
||||
{
|
||||
tail = _tail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)this).GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System;
|
||||
|
||||
namespace ProcessHacker.Common.Threading
|
||||
{
|
||||
public class FastStack<T> : IEnumerable<T>
|
||||
{
|
||||
private class FastStackNode<U>
|
||||
{
|
||||
public U Value;
|
||||
public FastStackNode<U> Next;
|
||||
}
|
||||
|
||||
private int _count = 0;
|
||||
private FastStackNode<T> _bottom = null;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
}
|
||||
|
||||
public T Peek()
|
||||
{
|
||||
FastStackNode<T> bottom;
|
||||
|
||||
bottom = _bottom;
|
||||
|
||||
if (bottom == null)
|
||||
throw new InvalidOperationException("The stack is empty.");
|
||||
|
||||
return bottom.Value;
|
||||
}
|
||||
|
||||
public T Pop()
|
||||
{
|
||||
FastStackNode<T> 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<FastStackNode<T>>(
|
||||
ref _bottom,
|
||||
bottom.Next,
|
||||
bottom
|
||||
) == bottom)
|
||||
{
|
||||
// Success.
|
||||
return bottom.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(T value)
|
||||
{
|
||||
FastStackNode<T> bottom;
|
||||
FastStackNode<T> entry;
|
||||
|
||||
entry = new FastStackNode<T>();
|
||||
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<FastStackNode<T>>(
|
||||
ref _bottom,
|
||||
entry,
|
||||
bottom
|
||||
) == bottom)
|
||||
{
|
||||
// Success.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
FastStackNode<T> entry;
|
||||
|
||||
entry = _bottom;
|
||||
|
||||
// Start the enumeration.
|
||||
while (entry != null)
|
||||
{
|
||||
yield return entry.Value;
|
||||
entry = entry.Next;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)this).GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user