aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/coroutine/engine/stack/stack.h
blob: 33de58a08576b95ae8f1cc3d21bb42ec2ad47d43 (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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma once

#include <util/generic/array_ref.h>
#include <util/generic/fwd.h>
#include <util/generic/noncopyable.h>

#include <cstdint>


namespace NCoro::NStack {

    class IAllocator;

namespace NDetails {

    //! Do not use directly, use TStackHolder instead
    class TStack final : private TMoveOnly {
    public:
        /*! rawMemory: can be used by unaligned allocator to free stack memory after use
         *  alignedMemory: pointer to aligned memory on which stack workspace and guard are actually placed
         *  alignedSize: size of workspace memory + memory for guard
         *  guard: guard to protect this stack
         *  name: name of coroutine for which this stack is allocated
         */
        TStack(void* rawMemory, void* alignedMemory, size_t alignedSize, const char* name);
        TStack(TStack&& rhs) noexcept;
        TStack& operator=(TStack&& rhs) noexcept;

        char* GetRawMemory() const noexcept {
            return RawMemory_;
        }

        char* GetAlignedMemory() const noexcept {
            return AlignedMemory_;
        }

        //! Stack size (includes memory for guard)
        size_t GetSize() const noexcept {
            return Size_;
        }

        //! Resets parameters, should be called after stack memory is freed
        void Reset() noexcept;

    private:
        char* RawMemory_ = nullptr; // not owned
        char* AlignedMemory_ = nullptr; // not owned
        size_t Size_ = 0;
    };

} // namespace NDetails

    class TStackHolder final : private TMoveOnly {
    public:
        explicit TStackHolder(IAllocator& allocator, uint32_t size, const char* name) noexcept;
        TStackHolder(TStackHolder&&) = default;
        TStackHolder& operator=(TStackHolder&&) = default;

        ~TStackHolder();

        char* GetAlignedMemory() const noexcept {
            return Stack_.GetAlignedMemory();
        }
        size_t GetSize() const noexcept {
            return Stack_.GetSize();
        }

        TArrayRef<char> Get() noexcept;
        bool LowerCanaryOk() const noexcept;
        bool UpperCanaryOk() const noexcept;

    private:
        IAllocator& Allocator_;
        NDetails::TStack Stack_;
    };

}