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:
wj32
2009-08-17 08:21:34 +00:00
parent abb8fb6915
commit a41364e4e4
5 changed files with 195 additions and 11 deletions
+2 -7
View File
@@ -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
+4 -4
View File
@@ -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();
}
}
}