14 [DebuggerDisplay(
"Count = {Count}")]
15 [DebuggerTypeProxy(typeof(SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<>))]
16 [__DynamicallyInvokable]
17 [HostProtection(
SecurityAction.LinkDemand, Synchronization =
true, ExternalThreading =
true)]
22 internal volatile T[] m_array;
24 internal volatile VolatileBool[] m_state;
26 private volatile Segment m_next;
28 internal readonly
long m_index;
30 private volatile int m_low;
32 private volatile int m_high;
36 internal Segment Next => m_next;
40 internal int Low =>
Math.
Min(m_low, 32);
47 m_state =
new VolatileBool[32];
53 internal void UnsafeAdd(
T value)
56 m_array[m_high] = value;
57 m_state[m_high].m_value =
true;
60 internal Segment UnsafeGrow()
62 return m_next =
new Segment(m_index + 1, m_source);
67 Segment segment = m_next =
new Segment(m_index + 1, m_source);
68 m_source.m_tail = m_next;
71 internal bool TryAppend(
T value)
87 m_state[num].m_value =
true;
97 internal bool TryRemove(out
T result)
107 while (!m_state[low].m_value)
111 result = m_array[low];
112 if (m_source.m_numSnapshotTakers <= 0)
114 m_array[low] =
default(
T);
119 while (m_next ==
null)
123 m_source.m_head = m_next;
144 while (!m_state[low].m_value)
148 result = m_array[low];
152 internal void AddToList(
List<T> list,
int start,
int end)
154 for (
int i = start; i <= end; i++)
157 while (!m_state[i].m_value)
161 list.Add(m_array[i]);
167 private volatile Segment m_head;
170 private volatile Segment m_tail;
172 private T[] m_serializationArray;
174 private const int SEGMENT_SIZE = 32;
177 internal volatile int m_numSnapshotTakers;
181 [__DynamicallyInvokable]
184 [__DynamicallyInvokable]
194 [__DynamicallyInvokable]
197 [__DynamicallyInvokable]
206 [__DynamicallyInvokable]
209 [__DynamicallyInvokable]
212 Segment head = m_head;
217 if (head.Next ==
null)
224 if (head.Next ==
null)
237 [__DynamicallyInvokable]
240 [__DynamicallyInvokable]
243 GetHeadTailPositions(out Segment head, out Segment tail, out
int headLow, out
int tailHigh);
246 return tailHigh - headLow + 1;
248 int num = 32 - headLow;
249 num += 32 * (int)(tail.m_index - head.m_index - 1);
250 return num + (tailHigh + 1);
255 [__DynamicallyInvokable]
258 m_head = (m_tail =
new Segment(0
L,
this));
263 Segment segment = m_head =
new Segment(0L,
this);
265 foreach (T item
in collection)
267 segment.UnsafeAdd(item);
271 segment = segment.UnsafeGrow();
281 [__DynamicallyInvokable]
284 if (collection ==
null)
288 InitializeFromCollection(collection);
294 m_serializationArray =
ToArray();
300 InitializeFromCollection(m_serializationArray);
301 m_serializationArray =
null;
313 [__DynamicallyInvokable]
325 [__DynamicallyInvokable]
334 [__DynamicallyInvokable]
335 bool IProducerConsumerCollection<T>.TryAdd(T item)
344 [__DynamicallyInvokable]
345 bool IProducerConsumerCollection<T>.TryTake(out T item)
352 [__DynamicallyInvokable]
355 return ToList().ToArray();
364 GetHeadTailPositions(out Segment head, out Segment tail, out
int headLow, out
int tailHigh);
367 head.AddToList(list, headLow, 31);
368 for (Segment next = head.Next; next != tail; next = next.Next)
370 next.AddToList(list, 0, 31);
372 tail.AddToList(list, 0, tailHigh);
375 head.AddToList(list, headLow, tailHigh);
384 private void GetHeadTailPositions(out Segment head, out Segment tail, out
int headLow, out
int tailHigh)
389 tailHigh = tail.High;
391 while (head != m_head || tail != m_tail || headLow != head.Low || tailHigh != tail.High || head.m_index > tail.m_index)
397 tailHigh = tail.High;
410 [__DynamicallyInvokable]
417 ToList().CopyTo(array, index);
422 [__DynamicallyInvokable]
426 GetHeadTailPositions(out Segment head, out Segment tail, out
int headLow, out
int tailHigh);
427 return GetEnumerator(head, tail, headLow, tailHigh);
430 private IEnumerator<T> GetEnumerator(Segment head, Segment tail,
int headLow,
int tailHigh)
437 for (
int l = headLow; l <= tailHigh; l++)
440 while (!head.m_state[l].m_value)
444 yield
return head.m_array[l];
449 for (
int k = headLow; k < 32; k++)
452 while (!head.m_state[k].m_value)
456 yield
return head.m_array[k];
458 for (Segment curr = head.Next; curr != tail; curr = curr.Next)
460 for (
int i = 0; i < 32; i++)
463 while (!curr.m_state[i].m_value)
467 yield
return curr.m_array[i];
470 for (
int j = 0; j <= tailHigh; j++)
473 while (!tail.m_state[j].m_value)
477 yield
return tail.m_array[j];
489 [__DynamicallyInvokable]
495 Segment tail = m_tail;
496 if (tail.TryAppend(item))
508 [__DynamicallyInvokable]
513 Segment head = m_head;
514 if (head.TryRemove(out result))
527 [__DynamicallyInvokable]
533 Segment head = m_head;
534 if (head.TryPeek(out result))
object SyncRoot
Gets an object that can be used to synchronize access to the T:System.Collections....
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
void Reset()
Resets the spin counter.
Provides support for spin-based waiting.
void CopyTo(T[] array, int index)
Copies the T:System.Collections.Concurrent.ConcurrentQueue`1 elements to an existing one-dimensional ...
static sbyte Min(sbyte val1, sbyte val2)
Returns the smaller of two 8-bit signed integers.
new IEnumerator< T > GetEnumerator()
Returns an enumerator that iterates through the collection.
bool TryPeek(out T result)
Tries to return an object from the beginning of the T:System.Collections.Concurrent....
Exposes the enumerator, which supports a simple iteration over a collection of a specified type....
bool TryDequeue(out T result)
Tries to remove and return the object at the beginning of the concurrent queue.
Represents a strongly-typed, read-only collection of elements.
ConcurrentQueue(IEnumerable< T > collection)
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentQueue`1 class that contai...
void CopyTo(T[] array, int arrayIndex)
Copies the elements of the T:System.Collections.Generic.ICollection`1 to an T:System....
Describes the source and destination of a given serialized stream, and provides an additional caller-...
bool IsEmpty
Gets a value that indicates whether the T:System.Collections.Concurrent.ConcurrentQueue`1 is empty.
Supports a simple iteration over a generic collection.
Defines methods to manipulate generic collections.
Exposes an enumerator, which supports a simple iteration over a non-generic collection....
SecurityAction
Specifies the security actions that can be performed using declarative security.
Provides information about, and means to manipulate, the current environment and platform....
Specifies that the process performs time-critical tasks that must be executed immediately,...
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
static int Increment(ref int location)
Increments a specified variable and stores the result, as an atomic operation.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
bool IsSynchronized
Gets a value indicating whether access to the T:System.Collections.ICollection is synchronized (threa...
void Enqueue(T item)
Adds an object to the end of the T:System.Collections.Concurrent.ConcurrentQueue`1.
ConcurrentQueue()
Initializes a new instance of the T:System.Collections.Concurrent.ConcurrentQueue`1 class.
Defines methods to manipulate thread-safe collections intended for producer/consumer usage....
IEnumerator< T > GetEnumerator()
Returns an enumerator that iterates through the T:System.Collections.Concurrent.ConcurrentQueue`1.
T [] ToArray()
Copies the elements stored in the T:System.Collections.Concurrent.ConcurrentQueue`1 to a new array.
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
void SpinOnce()
Performs a single spin.
Specifies that the class can be serialized.
Represents a thread-safe first in-first out (FIFO) collection.
static int Decrement(ref int location)
Decrements a specified variable and stores the result, as an atomic operation.
Provides constants and static methods for trigonometric, logarithmic, and other common mathematical f...
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
Defines size, enumerators, and synchronization methods for all nongeneric collections.
int Count
Gets the number of elements contained in the T:System.Collections.Concurrent.ConcurrentQueue`1.
Provides atomic operations for variables that are shared by multiple threads.