115 typedef typename ElementType::ConstReferenceType ConstReferenceType;
116 typedef typename ElementType::ReferenceType ReferenceType;
119 static inline int blockfor(
int &x)
121 x = x & ConstantsType::IndexMask;
122 for (
int i = 0; i < ConstantsType::BlockCount; ++i) {
123 int size = ConstantsType::Sizes[i];
128 Q_UNREACHABLE_RETURN(-1);
132 static inline ElementType *allocate(
int offset,
int size)
135 ElementType *v =
new ElementType[size];
136 for (
int i = 0; i < size; ++i)
137 v[i].next.storeRelaxed(offset + i + 1);
142 static inline int incrementserial(
int o,
int n)
144 return int((uint(n) & ConstantsType::IndexMask) | ((uint(o) + ConstantsType::SerialCounter) & ConstantsType::SerialMask));
148 QAtomicPointer<ElementType> _v[ConstantsType::BlockCount];
160 inline ConstReferenceType
at(
int x)
const;
164
165
166
205 id = _next.loadAcquire();
207 at = id & ConstantsType::IndexMask;
208 const int block = blockfor(at);
209 v = _v[block].loadAcquire();
212 v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]);
213 if (!_v[block].testAndSetRelease(
nullptr, v)) {
216 v = _v[block].loadAcquire();
217 Q_ASSERT(v !=
nullptr);
221 newid = v[at].next.loadRelaxed() | (id & ~ConstantsType::IndexMask);
222 }
while (!_next.testAndSetRelease(id, newid));
233 int at = id & ConstantsType::IndexMask;
234 const int block = blockfor(at);
235 ElementType *v = _v[block].loadRelaxed();
239 x = _next.loadAcquire();
240 v[at].next.storeRelaxed(x & ConstantsType::IndexMask);
242 newid = incrementserial(x, id);
243 }
while (!_next.testAndSetRelease(x, newid));