116 typedef typename ElementType::ConstReferenceType ConstReferenceType;
117 typedef typename ElementType::ReferenceType ReferenceType;
120 static inline int blockfor(
int &x)
122 x = x & ConstantsType::IndexMask;
123 for (
int i = 0; i < ConstantsType::BlockCount; ++i) {
124 int size = ConstantsType::Sizes[i];
129 Q_UNREACHABLE_RETURN(-1);
133 static inline ElementType *allocate(
int offset,
int size)
136 ElementType *v =
new ElementType[size];
137 for (
int i = 0; i < size; ++i)
138 v[i].next.storeRelaxed(offset + i + 1);
143 static inline int incrementserial(
int o,
int n)
145 return int((uint(n) & ConstantsType::IndexMask) | ((uint(o) + ConstantsType::SerialCounter) & ConstantsType::SerialMask));
149 QAtomicPointer<ElementType> _v[ConstantsType::BlockCount];
161 inline ConstReferenceType
at(
int x)
const;
165
166
167
204 int id = _next.loadAcquire();
206 int at = id & ConstantsType::IndexMask;
207 const int block = blockfor(at);
208 ElementType *v = _v[block].loadAcquire();
211 ElementType*
const alloced = allocate((id & ConstantsType::IndexMask) - at,
212 ConstantsType::Sizes[block]);
213 if (_v[block].testAndSetRelease(
nullptr, alloced, v)) {
218 Q_ASSERT(v !=
nullptr);
222 newid = v[at].next.loadRelaxed() | (id & ~ConstantsType::IndexMask);
223 }
while (!_next.testAndSetOrdered(id, newid, id));
234 int at = id & ConstantsType::IndexMask;
235 const int block = blockfor(at);
236 ElementType *v = _v[block].loadAcquire();
240 x = _next.loadAcquire();
241 v[at].next.storeRelaxed(x & ConstantsType::IndexMask);
243 newid = incrementserial(x, id);
244 }
while (!_next.testAndSetRelease(x, newid));