| 2921 | |
| 2922 | template<AllocationMode allocMode> |
| 2923 | inline bool insert_block_index_entry(BlockIndexEntry*& idxEntry, index_t blockStartIndex) |
| 2924 | { |
| 2925 | auto localBlockIndex = blockIndex.load(std::memory_order_relaxed); // We're the only writer thread, relaxed is OK |
| 2926 | if (localBlockIndex == nullptr) { |
| 2927 | return false; // this can happen if new_block_index failed in the constructor |
| 2928 | } |
| 2929 | size_t newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); |
| 2930 | idxEntry = localBlockIndex->index[newTail]; |
| 2931 | if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE || |
| 2932 | idxEntry->value.load(std::memory_order_relaxed) == nullptr) { |
| 2933 | |
| 2934 | idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); |
| 2935 | localBlockIndex->tail.store(newTail, std::memory_order_release); |
| 2936 | return true; |
| 2937 | } |
| 2938 | |
| 2939 | // No room in the old block index, try to allocate another one! |
| 2940 | MOODYCAMEL_CONSTEXPR_IF (allocMode == CannotAlloc) { |
| 2941 | return false; |
| 2942 | } |
| 2943 | else if (!new_block_index()) { |
| 2944 | return false; |
| 2945 | } |
| 2946 | else { |
| 2947 | localBlockIndex = blockIndex.load(std::memory_order_relaxed); |
| 2948 | newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1); |
| 2949 | idxEntry = localBlockIndex->index[newTail]; |
| 2950 | assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE); |
| 2951 | idxEntry->key.store(blockStartIndex, std::memory_order_relaxed); |
| 2952 | localBlockIndex->tail.store(newTail, std::memory_order_release); |
| 2953 | return true; |
| 2954 | } |
| 2955 | } |
| 2956 | |
| 2957 | inline void rewind_block_index_tail() |
nothing calls this directly
no test coverage detected