mpmc_unordered_ring.h 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. #pragma once
  2. /*
  3. It's not a general purpose queue.
  4. No order guarantee, but it mostly ordered.
  5. Items may stuck in almost empty queue.
  6. Use UnsafeScanningPop to pop all stuck items.
  7. Almost wait-free for producers and consumers.
  8. */
  9. #include <library/cpp/deprecated/atomic/atomic.h>
  10. #include <util/generic/ptr.h>
  11. namespace NThreading {
  12. struct TMPMCUnorderedRing {
  13. public:
  14. static constexpr ui16 MAX_PUSH_TRIES = 4;
  15. static constexpr ui16 MAX_POP_TRIES = 4;
  16. TMPMCUnorderedRing(size_t size);
  17. bool Push(void* msg, ui16 retryCount = MAX_PUSH_TRIES) noexcept;
  18. void StubbornPush(void* msg) {
  19. while (!WeakPush(msg)) {
  20. }
  21. }
  22. void* Pop() noexcept;
  23. void* UnsafeScanningPop(ui64* last) noexcept;
  24. private:
  25. bool WeakPush(void* msg) noexcept;
  26. size_t RingSize;
  27. TArrayPtr<void*> RingBuffer;
  28. ui64 WritePawl = 0;
  29. ui64 WriteFront = 0;
  30. ui64 ReadPawl = 0;
  31. ui64 ReadFront = 0;
  32. };
  33. }