| 3156 | |
| 3157 | private: |
| 3158 | static MemStats getFor(ConcurrentQueue* q) |
| 3159 | { |
| 3160 | MemStats stats = { 0 }; |
| 3161 | |
| 3162 | stats.elementsEnqueued = q->size_approx(); |
| 3163 | |
| 3164 | auto block = q->freeList.head_unsafe(); |
| 3165 | while (block != nullptr) { |
| 3166 | ++stats.allocatedBlocks; |
| 3167 | ++stats.freeBlocks; |
| 3168 | block = block->freeListNext.load(std::memory_order_relaxed); |
| 3169 | } |
| 3170 | |
| 3171 | for (auto ptr = q->producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { |
| 3172 | bool implicit = dynamic_cast<ImplicitProducer*>(ptr) != nullptr; |
| 3173 | stats.implicitProducers += implicit ? 1 : 0; |
| 3174 | stats.explicitProducers += implicit ? 0 : 1; |
| 3175 | |
| 3176 | if (implicit) { |
| 3177 | auto prod = static_cast<ImplicitProducer*>(ptr); |
| 3178 | stats.queueClassBytes += sizeof(ImplicitProducer); |
| 3179 | auto head = prod->headIndex.load(std::memory_order_relaxed); |
| 3180 | auto tail = prod->tailIndex.load(std::memory_order_relaxed); |
| 3181 | auto hash = prod->blockIndex.load(std::memory_order_relaxed); |
| 3182 | if (hash != nullptr) { |
| 3183 | for (size_t i = 0; i != hash->capacity; ++i) { |
| 3184 | if (hash->index[i]->key.load(std::memory_order_relaxed) != ImplicitProducer::INVALID_BLOCK_BASE && hash->index[i]->value.load(std::memory_order_relaxed) != nullptr) { |
| 3185 | ++stats.allocatedBlocks; |
| 3186 | ++stats.ownedBlocksImplicit; |
| 3187 | } |
| 3188 | } |
| 3189 | stats.implicitBlockIndexBytes += hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry); |
| 3190 | for (; hash != nullptr; hash = hash->prev) { |
| 3191 | stats.implicitBlockIndexBytes += sizeof(typename ImplicitProducer::BlockIndexHeader) + hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry*); |
| 3192 | } |
| 3193 | } |
| 3194 | for (; details::circular_less_than<index_t>(head, tail); head += BLOCK_SIZE) { |
| 3195 | //auto block = prod->get_block_index_entry_for_index(head); |
| 3196 | ++stats.usedBlocks; |
| 3197 | } |
| 3198 | } |
| 3199 | else { |
| 3200 | auto prod = static_cast<ExplicitProducer*>(ptr); |
| 3201 | stats.queueClassBytes += sizeof(ExplicitProducer); |
| 3202 | auto tailBlock = prod->tailBlock; |
| 3203 | bool wasNonEmpty = false; |
| 3204 | if (tailBlock != nullptr) { |
| 3205 | auto block = tailBlock; |
| 3206 | do { |
| 3207 | ++stats.allocatedBlocks; |
| 3208 | if (!block->ConcurrentQueue::Block::template is_empty<explicit_context>() || wasNonEmpty) { |
| 3209 | ++stats.usedBlocks; |
| 3210 | wasNonEmpty = wasNonEmpty || block != tailBlock; |
| 3211 | } |
| 3212 | ++stats.ownedBlocksExplicit; |
| 3213 | block = block->next; |
| 3214 | } while (block != tailBlock); |
| 3215 | } |
nothing calls this directly
no test coverage detected