internal static bool RemoveSequence <T>(
            T holder
            , _Volatile.AtomicReference <Sequence[]> sequenceUpdater
            , Sequence sequence)
        {
            int numToRemove;

            Sequence[] oldSequences;
            Sequence[] newSequences;
            //var casSequence = new T[1] { holder } as Sequence[];
            do
            {
                //oldSequences = sequenceUpdater.ReadUnfenced();
                oldSequences = sequenceUpdater.ReadCompilerOnlyFence();
                numToRemove  = CountMatching(oldSequences, sequence);
                if (0 == numToRemove)
                {
                    break;
                }
                int oldSize = oldSequences.Length;
                newSequences = new Sequence[oldSize - numToRemove];
                for (int i = 0, pos = 0; i < oldSize; i++)
                {
                    Sequence testSequence = oldSequences[i];
                    if (sequence != testSequence)
                    {
                        newSequences[pos++] = testSequence;
                    }
                }
            }while (!sequenceUpdater.AtomicCompareExchange(newSequences, oldSequences));

            return(numToRemove != 0);
        }
        internal static void AddSequences <T>(
            T holder
            , _Volatile.AtomicReference <Sequence[]> sequenceUpdater
            , ICursored cursor
            , params Sequence[] sequencesToAdd)
        {
            long cursorSequence;

            Sequence[] currentSequences;
            Sequence[] updatedSequences;
            //var casSequence = new T[1] { holder } as Sequence[];
            do
            {
                //currentSequences = sequenceUpdater.ReadUnfenced();
                currentSequences = sequenceUpdater.ReadCompilerOnlyFence();
                updatedSequences = Util.CopyToNewArray(currentSequences
                                                       , currentSequences.Length + sequencesToAdd.Length);
                cursorSequence = cursor.GetCursor;

                int index = currentSequences.Length;
                foreach (Sequence sequence in sequencesToAdd)
                {
                    sequence.LazySet(cursorSequence);
                    updatedSequences[index++] = sequence;
                }
            }while(!sequenceUpdater.AtomicCompareExchange(updatedSequences, currentSequences));
            cursorSequence = cursor.GetCursor;
            foreach (Sequence sequence in sequencesToAdd)
            {
                sequence.LazySet(cursorSequence);
            }
        }
Beispiel #3
0
 /// <summary>
 /// Add a <see cref="Sequence"/> into this aggregate.  This should only be used during
 /// initialisation.  Use <see cref="SequenceGroup.AddWhileRunning(Cursored, Sequence)"/>
 /// </summary>
 /// <param name="sequence"></param>
 public void Add(Sequence sequence)
 {
     Sequence[] oldSequences;
     Sequence[] newSequences;
     do
     {
         oldSequences = sequencesRef.ReadFullFence();
         var oldSize = oldSequences.Length;
         newSequences = new Sequence[oldSize + 1];
         Array.Copy(oldSequences, newSequences, oldSize);
         newSequences[oldSize] = sequence;
     }while (!sequencesRef.AtomicCompareExchange(newSequences, oldSequences));
 }
Beispiel #4
0
 public void AtomicCompareExchangeReturnsTrueIfComparandEqualsCurrentValue()
 {
     Assert.IsTrue(_volatile.AtomicCompareExchange(_newValue, _initialValue));
 }