using System; using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System.Threading; using glue; using glue.Debugging; #pragma warning disable 0649 namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sealed public class SpinLockTray : Tray { public SpinLockTray(int tix, TypeMgr tm, int next_mark, int next_id) : base(tix, tm, next_mark, next_id) { for (int i = 0; i < Pools.Length; i++) Pools[i] = new SpinLockTrayConstraintPool(this, i); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public sealed class SpinLockTrayConstraintPool : ConstraintPool { public SpinLockTrayConstraintPool(Tray tr, int i_feat) : base(tr, i_feat) { Nop.X(fsp1, fsp2); } FalseSharing.Padding60 fsp1; SpinLock m_lock = new SpinLock(false); // do not make this 'readonly' FalseSharing.Padding60 fsp2; Dictionary<Int32, Edge> dict = new Dictionary<Int32, Edge>(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override Edge GetEdge(Int32 m) { Debug.Assert(m != 0); bool entered = false; try { m_lock.Enter(ref entered); Edge c; dict.TryGetValue(m, out c); return c; } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool TryGetEdge(Int32 m, out Edge e) { Debug.Assert(m != 0); bool entered = false; try { m_lock.Enter(ref entered); return dict.TryGetValue(m, out e); } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Store the constraint for the specified mark. Handle Edge value semantics properly. /// Allows detached mark to be set for bare or atomic types /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void SetEdge(Int32 m, Edge c) { Debug.Assert(m != 0 && m >= tr._protect_mark && c.FlagsId != 0); bool entered = false; try { m_lock.Enter(ref entered); dict[m] = c; } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override void RemoveEdge(Int32 m) { Debug.Assert(m != 0 && m >= tr._protect_mark); bool entered = false; try { m_lock.Enter(ref entered); dict.Remove(m); } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool TryRemoveEdge(Int32 m, out Edge e) { Debug.Assert(m != 0 && m >= tr._protect_mark); bool entered = false; try { m_lock.Enter(ref entered); return dict.TryGetValue(m, out e) ? dict.Remove(m) : false; } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override bool ContainsInMark(Int32 m) { Debug.Assert(m != 0); bool entered = false; try { m_lock.Enter(ref entered); return dict.ContainsKey(m); } finally { if (entered) m_lock.Exit(false); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override int Count { get { bool entered = false; try { m_lock.Enter(ref entered); return dict.Count; } finally { if (entered) m_lock.Exit(false); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// not locked /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<int> Marks { get { tr.mre_truncate_ok.WaitOne(); return dict.Keys; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<Edge> Edges { get { tr.mre_truncate_ok.WaitOne(); return dict.Values; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override IEnumerable<KeyValuePair<int, Edge>> PoolEdges { get { tr.mre_truncate_ok.WaitOne(); return dict; } } }; }; }