aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/queue/mpmc_unordered_ring.h
blob: d776240efc3338bf0d8be850a6658d20c9398f3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#pragma once

/*
  It's not a general purpose queue.
  No order guarantee, but it mostly ordered.
  Items may stuck in almost empty queue.
  Use UnsafeScanningPop to pop all stuck items.
  Almost wait-free for producers and consumers.
 */

#include <library/cpp/deprecated/atomic/atomic.h>
#include <util/generic/ptr.h>

namespace NThreading {
    struct TMPMCUnorderedRing {
    public:
        static constexpr ui16 MAX_PUSH_TRIES = 4;
        static constexpr ui16 MAX_POP_TRIES = 4;

        TMPMCUnorderedRing(size_t size);

        bool Push(void* msg, ui16 retryCount = MAX_PUSH_TRIES) noexcept;
        void StubbornPush(void* msg) {
            while (!WeakPush(msg)) {
            }
        }

        void* Pop() noexcept;

        void* UnsafeScanningPop(ui64* last) noexcept;

    private:
        bool WeakPush(void* msg) noexcept;

        size_t RingSize;
        TArrayPtr<void*> RingBuffer;
        ui64 WritePawl = 0;
        ui64 WriteFront = 0;
        ui64 ReadPawl = 0;
        ui64 ReadFront = 0;
    };
}