| 3112 | |
| 3113 | private: |
| 3114 | static MemStats getFor(ConcurrentQueue* q) |
| 3115 | { |
| 3116 | MemStats stats = { 0 }; |
| 3117 | |
| 3118 | stats.elementsEnqueued = q->size_approx(); |
| 3119 | |
| 3120 | auto block = q->freeList.head_unsafe(); |
| 3121 | while (block != nullptr) { |
| 3122 | ++stats.allocatedBlocks; |
| 3123 | ++stats.freeBlocks; |
| 3124 | block = block->freeListNext.load(std::memory_order_relaxed); |
| 3125 | } |
| 3126 | |
| 3127 | for (auto ptr = q->producerListTail.load(std::memory_order_acquire); ptr != nullptr; ptr = ptr->next_prod()) { |
| 3128 | bool implicit = dynamic_cast<ImplicitProducer*>(ptr) != nullptr; |
| 3129 | stats.implicitProducers += implicit ? 1 : 0; |
| 3130 | stats.explicitProducers += implicit ? 0 : 1; |
| 3131 | |
| 3132 | if (implicit) { |
| 3133 | auto prod = static_cast<ImplicitProducer*>(ptr); |
| 3134 | stats.queueClassBytes += sizeof(ImplicitProducer); |
| 3135 | auto head = prod->headIndex.load(std::memory_order_relaxed); |
| 3136 | auto tail = prod->tailIndex.load(std::memory_order_relaxed); |
| 3137 | auto hash = prod->blockIndex.load(std::memory_order_relaxed); |
| 3138 | if (hash != nullptr) { |
| 3139 | for (size_t i = 0; i != hash->capacity; ++i) { |
| 3140 | if (hash->index[i]->key.load(std::memory_order_relaxed) != ImplicitProducer::INVALID_BLOCK_BASE && hash->index[i]->value.load(std::memory_order_relaxed) != nullptr) { |
| 3141 | ++stats.allocatedBlocks; |
| 3142 | ++stats.ownedBlocksImplicit; |
| 3143 | } |
| 3144 | } |
| 3145 | stats.implicitBlockIndexBytes += hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry); |
| 3146 | for (; hash != nullptr; hash = hash->prev) { |
| 3147 | stats.implicitBlockIndexBytes += sizeof(typename ImplicitProducer::BlockIndexHeader) + hash->capacity * sizeof(typename ImplicitProducer::BlockIndexEntry*); |
| 3148 | } |
| 3149 | } |
| 3150 | for (; details::circular_less_than<index_t>(head, tail); head += BLOCK_SIZE) { |
| 3151 | //auto block = prod->get_block_index_entry_for_index(head); |
| 3152 | ++stats.usedBlocks; |
| 3153 | } |
| 3154 | } |
| 3155 | else { |
| 3156 | auto prod = static_cast<ExplicitProducer*>(ptr); |
| 3157 | stats.queueClassBytes += sizeof(ExplicitProducer); |
| 3158 | auto tailBlock = prod->tailBlock; |
| 3159 | bool wasNonEmpty = false; |
| 3160 | if (tailBlock != nullptr) { |
| 3161 | auto block = tailBlock; |
| 3162 | do { |
| 3163 | ++stats.allocatedBlocks; |
| 3164 | if (!block->ConcurrentQueue::Block::template is_empty<explicit_context>() || wasNonEmpty) { |
| 3165 | ++stats.usedBlocks; |
| 3166 | wasNonEmpty = wasNonEmpty || block != tailBlock; |
| 3167 | } |
| 3168 | ++stats.ownedBlocksExplicit; |
| 3169 | block = block->next; |
| 3170 | } while (block != tailBlock); |
| 3171 | } |
nothing calls this directly
no test coverage detected