aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/coroutine/engine/stack/stack_storage.cpp
blob: 121c1f5b0f8f307d80df41d3bf069ad533ed65a6 (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
#include "stack_storage.h"

#include "stack.h"
#include "stack_utils.h"

#include <library/cpp/coroutine/engine/impl.h>


namespace NCoro::NStack {

    TStorage::TStorage(size_t stackSize, size_t rssPagesToKeep, size_t releaseRate)
        : StackSize_(stackSize)
        , RssPagesToKeep_(rssPagesToKeep)
        , ReleaseRate_(releaseRate ? releaseRate : 1)
    {
        Y_ASSERT(StackSize_ && RssPagesToKeep_);
    }

    bool TStorage::IsEmpty() const noexcept {
        return Released_.empty() && Full_.empty();
    }

    size_t TStorage::Size() const noexcept {
        return Released_.size() + Full_.size();
    }

    void TStorage::ReturnStack(NDetails::TStack& stack) {
        thread_local size_t i = 0;
        if (++i % ReleaseRate_ != 0) {
            Full_.push_back(stack.GetAlignedMemory());
        } else {
            ReleaseMemory(stack.GetAlignedMemory(), RssPagesToKeep_);
            Released_.push_back(stack.GetAlignedMemory());
        }
        stack.Reset();
    }

    void TStorage::ReleaseMemory([[maybe_unused]] char* alignedStackMemory, [[maybe_unused]] size_t pagesToKeep) noexcept {
#if !defined(_san_enabled_) && defined(NDEBUG)
        size_t numOfPagesToFree = StackSize_ / PageSize;
        numOfPagesToFree -= pagesToKeep;
        ReleaseRss(alignedStackMemory, numOfPagesToFree);
#endif
    }

}