Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
SingleProducerSingleConsumerQueue.cs
Go to the documentation of this file.
6using Internal;
7
9
10[DebuggerDisplay("Count = {Count}")]
11[DebuggerTypeProxy(typeof(SingleProducerSingleConsumerQueue<>.SingleProducerSingleConsumerQueue_DebugView))]
13{
14 [StructLayout(LayoutKind.Sequential)]
15 private sealed class Segment
16 {
17 internal Segment _next;
18
19 internal readonly T[] _array;
20
22
23 internal Segment(int size)
24 {
25 _array = new T[size];
26 }
27 }
28
29 private struct SegmentState
30 {
32
33 internal volatile int _first;
34
35 internal int _lastCopy;
36
38
39 internal int _firstCopy;
40
41 internal volatile int _last;
42
44 }
45
58
59 private volatile Segment _head;
60
61 private volatile Segment _tail;
62
63 public bool IsEmpty
64 {
65 get
66 {
67 Segment head = _head;
68 if (head._state._first != head._state._lastCopy)
69 {
70 return false;
71 }
72 if (head._state._first != head._state._last)
73 {
74 return false;
75 }
76 return head._next == null;
77 }
78 }
79
80 internal int Count
81 {
82 get
83 {
84 int num = 0;
85 for (Segment segment = _head; segment != null; segment = segment._next)
86 {
87 int num2 = segment._array.Length;
88 int first;
89 int last;
90 do
91 {
92 first = segment._state._first;
93 last = segment._state._last;
94 }
95 while (first != segment._state._first);
96 num += (last - first) & (num2 - 1);
97 }
98 return num;
99 }
100 }
101
103 {
104 _head = (_tail = new Segment(32));
105 }
106
107 public void Enqueue(T item)
108 {
110 T[] array = segment._array;
111 int last = segment._state._last;
112 int num = (last + 1) & (array.Length - 1);
113 if (num != segment._state._firstCopy)
114 {
115 array[last] = item;
116 segment._state._last = num;
117 }
118 else
119 {
121 }
122 }
123
125 {
126 if (segment._state._firstCopy != segment._state._first)
127 {
128 segment._state._firstCopy = segment._state._first;
129 Enqueue(item);
130 return;
131 }
132 int num = _tail._array.Length << 1;
133 if (num > 16777216)
134 {
135 num = 16777216;
136 }
137 Segment segment2 = new Segment(num);
138 segment2._array[0] = item;
139 segment2._state._last = 1;
140 segment2._state._lastCopy = 1;
141 try
142 {
143 }
144 finally
145 {
147 _tail = segment2;
148 }
149 }
150
151 public bool TryDequeue([MaybeNullWhen(false)] out T result)
152 {
153 Segment head = _head;
154 T[] array = head._array;
155 int first = head._state._first;
156 if (first != head._state._lastCopy)
157 {
158 result = array[first];
159 array[first] = default(T);
160 head._state._first = (first + 1) & (array.Length - 1);
161 return true;
162 }
163 return TryDequeueSlow(head, array, peek: false, out result);
164 }
165
166 public bool TryPeek([MaybeNullWhen(false)] out T result)
167 {
168 Segment head = _head;
169 T[] array = head._array;
170 int first = head._state._first;
171 if (first != head._state._lastCopy)
172 {
173 result = array[first];
174 return true;
175 }
176 return TryDequeueSlow(head, array, peek: true, out result);
177 }
178
179 private bool TryDequeueSlow(Segment segment, T[] array, bool peek, [MaybeNullWhen(false)] out T result)
180 {
181 if (segment._state._last != segment._state._lastCopy)
182 {
183 segment._state._lastCopy = segment._state._last;
184 if (!peek)
185 {
186 return TryDequeue(out result);
187 }
188 return TryPeek(out result);
189 }
190 if (segment._next != null && segment._state._first == segment._state._last)
191 {
192 segment = segment._next;
193 array = segment._array;
194 _head = segment;
195 }
196 int first = segment._state._first;
197 if (first == segment._state._last)
198 {
199 result = default(T);
200 return false;
201 }
202 result = array[first];
203 if (!peek)
204 {
205 array[first] = default(T);
206 segment._state._first = (first + 1) & (segment._array.Length - 1);
207 segment._state._lastCopy = segment._state._last;
208 }
209 return true;
210 }
211
213 {
214 for (Segment segment = _head; segment != null; segment = segment._next)
215 {
216 for (int pt = segment._state._first; pt != segment._state._last; pt = (pt + 1) & (segment._array.Length - 1))
217 {
218 yield return segment._array[pt];
219 }
220 }
221 }
222
227}
bool TryDequeueSlow(Segment segment, T[] array, bool peek, [MaybeNullWhen(false)] out T result)
static void Write(ref bool location, bool value)
Definition Volatile.cs:74