using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
#pragma warning disable 0649
namespace miew.Concurrency
{
static public class Tasks
{
static Tasks()
{
TaskCompletionSource<Object> tcs = new TaskCompletionSource<Object>();
tcs.SetResult(null);
CompletedTask = tcs.Task;
}
static readonly public Task CompletedTask;
static public Task<T> FromResult<T>(T result)
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(TaskCreationOptions.AttachedToParent);
tcs.SetResult(result);
return tcs.Task;
}
/// <summary>
/// Caution: elements in the enumeration might be iterated more than once; beware of side-effects
/// </summary>
//static public Task WhenAllXX(IEnumerable<Task> iet)
//{
// var c = iet as ICollection<Task>;
// if ((c != null && c.Count > 0) || iet.GetEnumerator().MoveNext())
// return TaskEx.WhenAll(iet);
// return CompletedTask;
//}
static public void RgtaskNop(Task[] rgt) { }
public static Task Self
{
get
{
return Task.Factory.StartNew(Nop, CancellationToken.None, TaskCreationOptions.AttachedToParent, TaskScheduler.Default).Parent();
}
}
static void Nop() { }
};
public class TimedTask<T> : Task<T>
{
public TimedTask(Func<T> f)
: base(f)
{
}
public long Milliseconds { get { return ms; } }
protected long ms;
public new void Start()
{
Stopwatch sw = Stopwatch.StartNew();
base.Start();
base.ContinueWith(t => ms = sw.ElapsedMilliseconds, TaskContinuationOptions.ExecuteSynchronously);
}
};
static public class Extensions
{
public static Task Parent(this Task t)
{
FieldInfo info = typeof(Task).GetField("m_parent", BindingFlags.NonPublic | BindingFlags.Instance);
return info != null ? (Task)info.GetValue(t) : null;
}
public static bool HasAsAncestor(this Task t, Task parent)
{
Task walk = t;
while ((walk = walk.Parent()) != null)
if (walk == t)
return true;
return false;
}
public static bool AtomicStoreIfNull<T>(ref T pt, ref T in_out) where T : class
{
T actual = Interlocked.CompareExchange<T>(ref pt, in_out, null);
if (actual == null)
return true;
in_out = actual;
return false;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public sealed class ConcurrentList<T> : List<T>//: ConcurrentContainer<T>
{
//readonly List<T> list = new List<T>();
SpinLock m_lock = new SpinLock(false); // do not make this 'readonly'
public ConcurrentList()
{
}
public ConcurrentList(T t)
{
this.Add(t);
}
public new /*override*/ void Clear()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
base.Clear();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public new /*override*/ bool Add(T item)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
base.Add(item);
return true;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public new void AddRange(IEnumerable<T> items)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
base.AddRange(items);
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
/// <summary>
/// (useless for concurrency)
/// </summary>
public new /*override*/ bool Contains(T item)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return base.Contains(item);
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
/// <summary>
/// (useless for concurrency)
/// </summary>
public new /*override*/ int Count
{
get
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return base.Count;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
}
public new /*override*/ IEnumerator<T> GetEnumerator()
{
while (true)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return base.ToArray().AsEnumerable<T>().GetEnumerator();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
}
public IEnumerable<T> GetEnumerableUnsafe()
{
return base.ToArray().AsEnumerable<T>();
}
public new T[] ToArray()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return base.ToArray();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
/// <summary>
///
/// </summary>
public new /*override*/ bool Remove(T item) { throw new NotImplementedException(); }
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public sealed class ConcurrentHashSet<T> : ConcurrentContainer<T>
{
readonly HashSet<T> hs = new HashSet<T>();
SpinLock m_lock = new SpinLock(false); // do not make this 'readonly'
T any = default(T);
public T Peek() { return any; }
public override bool Add(T item)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
bool b = hs.Add(item);
if (b)
any = item;
return b;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public override bool Remove(T item)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
bool b = hs.Remove(item);
if (b && any.Equals(item))
{
if (hs.Count == 0)
any = default(T);
else
{
var e = hs.GetEnumerator();
e.MoveNext();
any = e.Current;
}
}
return b;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public override void Clear()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
hs.Clear();
any = default(T);
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public override bool Contains(T item)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return hs.Contains(item);
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public T[] ToArray()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return hs.ToArray();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public override IEnumerator<T> GetEnumerator()
{
return ToArray().AsEnumerable<T>().GetEnumerator();
}
public override int Count { get { return hs.Count; } }
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class ConcurrentStringBuilder
{
readonly System.Text.StringBuilder sb = new System.Text.StringBuilder();
SpinLock m_lock = new SpinLock(false); // do not make this 'readonly'
public void Clear()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
sb.Clear();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public ConcurrentStringBuilder Append(System.String s)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
sb.Append(s);
return this;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public ConcurrentStringBuilder AppendFormat(System.String fmt, params Object[] args)
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
sb.AppendFormat(fmt, args);
return this;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public override System.String ToString()
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return sb.ToString();
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
public int Length
{
get
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
return sb.Length;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
set
{
bool entered = false;
try
{
m_lock.Enter(ref entered);
sb.Length = value;
}
finally
{
if (entered)
m_lock.Exit(false);
}
}
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public abstract class ConcurrentContainer<T> : ISet<T>
{
public abstract bool Add(T item);
public abstract void Clear();
public abstract bool Contains(T item);
public abstract int Count { get; }
public abstract bool Remove(T item);
public virtual IEnumerator<T> GetEnumerator() { throw new NotImplementedException(); }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
void ICollection<T>.Add(T item) { Add(item); }
public bool IsReadOnly { get { return false; } }
public void CopyTo(T[] array, int arrayIndex) { throw new NotSupportedException(); }
public void ExceptWith(IEnumerable<T> other) { throw new NotSupportedException(); }
public void IntersectWith(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool IsProperSubsetOf(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool IsProperSupersetOf(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool IsSubsetOf(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool IsSupersetOf(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool Overlaps(IEnumerable<T> other) { throw new NotSupportedException(); }
public bool SetEquals(IEnumerable<T> other) { throw new NotSupportedException(); }
public void SymmetricExceptWith(IEnumerable<T> other) { throw new NotSupportedException(); }
public void UnionWith(IEnumerable<T> other) { throw new NotSupportedException(); }
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public sealed class ConcurrentSymmetricDictionary<K1, K2>
{
FalseSharing.Padding60 fsp1;
SpinLock slock = new SpinLock(false); // do not make this 'readonly'
FalseSharing.Padding60 fsp2;
Dictionary<K1, K2> forward;
Dictionary<K2, K1> reverse;
public ConcurrentSymmetricDictionary(IEqualityComparer<K1> c)
{
forward = new Dictionary<K1, K2>(c);
reverse = new Dictionary<K2, K1>();
Debugging.Nop.X(fsp1, fsp2);
}
public ConcurrentSymmetricDictionary(IEqualityComparer<K2> c)
{
forward = new Dictionary<K1, K2>();
reverse = new Dictionary<K2, K1>(c);
Debugging.Nop.X(fsp1, fsp2);
}
public ConcurrentSymmetricDictionary()
{
forward = new Dictionary<K1, K2>();
reverse = new Dictionary<K2, K1>();
Debugging.Nop.X(fsp1, fsp2);
}
public K2 this[K1 k1]
{
get
{
return forward[k1];
}
set
{
bool _b = false;
try
{
slock.Enter(ref _b);
forward[k1] = value;
reverse[value] = k1;
}
finally
{
if (_b) slock.Exit();
}
}
}
public K1 this[K2 k2]
{
get
{
return reverse[k2];
}
set
{
bool _b = false;
try
{
slock.Enter(ref _b);
reverse[k2] = value;
forward[value] = k2;
}
finally
{
if (_b) slock.Exit();
}
}
}
public void Add(K1 k1, K2 k2)
{
bool _b = false;
try
{
slock.Enter(ref _b);
forward.Add(k1, k2);
reverse.Add(k2, k1);
}
finally
{
if (_b) slock.Exit();
}
}
public bool Remove(K1 k1)
{
bool _b = false;
try
{
slock.Enter(ref _b);
K2 k2;
if (!forward.TryGetValue(k1, out k2))
return false;
forward.Remove(k1);
reverse.Remove(k2);
return true;
}
finally
{
if (_b) slock.Exit();
}
}
public bool Remove(K2 k2)
{
bool _b = false;
try
{
slock.Enter(ref _b);
K1 k1;
if (!reverse.TryGetValue(k2, out k1))
return false;
reverse.Remove(k2);
forward.Remove(k1);
}
finally
{
if (_b) slock.Exit();
}
return true;
}
public void Clear()
{
bool _b = false;
try
{
slock.Enter(ref _b);
forward.Clear();
reverse.Clear();
}
finally
{
if (_b) slock.Exit();
}
}
//public bool TryGetValue(K2 k2, out K1 k1)
//{
// return reverse.TryGetValue(k2, out k1);
//}
//public bool TryGetValue(K1 k1, out K2 k2)
//{
// return forward.TryGetValue(k1, out k2);
//}
public bool ContainsKey(K1 k1)
{
bool _b = false;
try
{
slock.Enter(ref _b);
return forward.ContainsKey(k1);
}
finally
{
if (_b) slock.Exit();
}
}
public bool ContainsKey(K2 k2)
{
bool _b = false;
try
{
slock.Enter(ref _b);
return reverse.ContainsKey(k2);
}
finally
{
if (_b) slock.Exit();
}
}
public bool TryGetKey(K1 k1, out K2 k2)
{
bool _b = false;
try
{
slock.Enter(ref _b);
return forward.TryGetValue(k1, out k2);
}
finally
{
if (_b) slock.Exit();
}
}
public K2 GetOrAdd(K1 k1, K2 k2)
{
bool _b = false;
try
{
slock.Enter(ref _b);
K2 v;
if (!forward.TryGetValue(k1, out v))
{
v = k2;
forward.Add(k1, v);
reverse.Add(v, k1);
}
return v;
}
finally
{
if (_b) slock.Exit();
}
}
public int Count { get { return forward.Count; } }
public IEnumerable<KeyValuePair<K1, K2>> Enumerate()
{
return forward;
}
};
public static class FalseSharing
{
[StructLayout(LayoutKind.Explicit, Size = 56)]
public struct Padding56
{
};
[StructLayout(LayoutKind.Explicit, Size = 60)]
public struct Padding60
{
};
[StructLayout(LayoutKind.Explicit, Size = 64)]
public struct Padding64
{
};
[StructLayout(LayoutKind.Explicit, Size = 120)]
public struct Padding120
{
};
[StructLayout(LayoutKind.Explicit, Size = 124)]
public struct Padding124
{
};
[StructLayout(LayoutKind.Explicit, Size = 128)]
public struct Padding128
{
};
[StructLayout(LayoutKind.Explicit, Size = 248)]
public struct Padding248
{
};
[StructLayout(LayoutKind.Explicit, Size = 252)]
public struct Padding252
{
};
[StructLayout(LayoutKind.Explicit, Size = 256)]
public struct Padding256
{
};
[StructLayout(LayoutKind.Explicit, Size = 2048)]
public struct Padding2048
{
};
};
}