blob: 1a55d4a8c1b04a2ff92900da0aa5752b511c3956 (
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
|
#pragma once
#include "stack.h"
#include <util/datetime/base.h>
#include <util/generic/deque.h>
class TCont;
namespace NCoro::NStack {
class IGuard;
class TStorage final : private TMoveOnly {
public:
TStorage(size_t stackSize, size_t rssPagesToKeep, size_t releaseRate);
bool IsEmpty() const noexcept;
size_t Size() const noexcept;
size_t GetReleasedSize() const noexcept { return Released_.size(); }
size_t GetFullSize() const noexcept { return Full_.size(); }
template<typename TGuard>
NDetails::TStack GetStack(const TGuard& guard, const char* name);
void ReturnStack(NDetails::TStack& stack);
private:
void ReleaseMemory(char* alignedStackMemory, size_t pagesToKeep) noexcept;
private:
TDeque<void*> Released_; //!< stacks memory with released RSS memory
TDeque<void*> Full_; //!< stacks memory with RSS memory
size_t StackSize_ = 0;
size_t RssPagesToKeep_ = 0;
const size_t ReleaseRate_ = 1;
};
template<typename TGuard>
NDetails::TStack TStorage::GetStack(const TGuard& guard, const char* name) {
Y_ABORT_UNLESS(!IsEmpty()); // check before call
void* newStack = nullptr;
if (!Full_.empty()) {
newStack = Full_.back();
Full_.pop_back();
} else {
Y_ASSERT(!Released_.empty());
newStack = Released_.back();
Released_.pop_back();
}
Y_ABORT_UNLESS(guard.CheckOverflow(newStack), "corrupted stack in pool");
Y_ABORT_UNLESS(guard.CheckOverride(newStack, StackSize_), "corrupted stack in pool");
return NDetails::TStack{newStack, newStack, StackSize_, name};
}
}
|