| 693 | #endif |
| 694 | |
| 695 | struct Block |
| 696 | { |
| 697 | // Avoid false-sharing by putting highly contended variables on their own cache lines |
| 698 | weak_atomic<size_t> front; // (Atomic) Elements are read from here |
| 699 | size_t localTail; // An uncontended shadow copy of tail, owned by the consumer |
| 700 | |
| 701 | char cachelineFiller0[MOODYCAMEL_CACHE_LINE_SIZE - sizeof(weak_atomic<size_t>) - sizeof(size_t)]; |
| 702 | weak_atomic<size_t> tail; // (Atomic) Elements are enqueued here |
| 703 | size_t localFront; |
| 704 | |
| 705 | char cachelineFiller1[MOODYCAMEL_CACHE_LINE_SIZE - sizeof(weak_atomic<size_t>) - sizeof(size_t)]; // next isn't very contended, but we don't want it on the same cache line as tail (which is) |
| 706 | weak_atomic<Block*> next; // (Atomic) |
| 707 | |
| 708 | char* data; // Contents (on heap) are aligned to T's alignment |
| 709 | |
| 710 | const size_t sizeMask; |
| 711 | |
| 712 | |
| 713 | // size must be a power of two (and greater than 0) |
| 714 | AE_NO_TSAN Block(size_t const& _size, char* _rawThis, char* _data) |
| 715 | : front(0UL), localTail(0), tail(0UL), localFront(0), next(nullptr), data(_data), sizeMask(_size - 1), rawThis(_rawThis) |
| 716 | { |
| 717 | } |
| 718 | |
| 719 | private: |
| 720 | // C4512 - Assignment operator could not be generated |
| 721 | Block& operator=(Block const&); |
| 722 | |
| 723 | public: |
| 724 | char* rawThis; |
| 725 | }; |
| 726 | |
| 727 | |
| 728 | static Block* make_block(size_t capacity) AE_NO_TSAN |
nothing calls this directly
no outgoing calls
no test coverage detected