17 #include <type_traits> 21 #if defined(BOOST_USE_VALGRIND) 22 #include <valgrind/valgrind.h> 31 template <
typename STACK_TRAITS>
34 _blocks(new Header*[size]),
36 _freeBlockIndex(size-1),
37 _numHeapAllocatedBlocks(0),
40 if (!_blocks || !_freeBlocks) {
41 throw std::bad_alloc();
44 throw std::runtime_error(
"Invalid coroutine allocator pool size");
48 _blocks[i] = reinterpret_cast<Header*>(
new char[_stackSize]);
50 throw std::bad_alloc();
60 template <
typename STACK_TRAITS>
66 template <
typename STACK_TRAITS>
70 _blocks = other._blocks;
71 _freeBlocks = other._freeBlocks;
72 _freeBlockIndex = other._freeBlockIndex;
73 _numHeapAllocatedBlocks = other._numHeapAllocatedBlocks;
76 other._blocks =
nullptr;
77 other._freeBlocks =
nullptr;
78 other._freeBlockIndex = -1;
79 other._numHeapAllocatedBlocks = 0;
82 template <
typename STACK_TRAITS>
85 for (
size_t i = 0; i < _size; ++i) {
86 delete[] (
char*)_blocks[i];
92 template <
typename STACK_TRAITS>
94 boost::context::stack_context ctx;
95 Header* block =
nullptr;
100 block = _blocks[_freeBlocks[_freeBlockIndex--]];
105 block = (Header*)
new char[_stackSize];
107 throw std::bad_alloc();
111 ++_numHeapAllocatedBlocks;
113 char* block_start = reinterpret_cast<char*>(block) +
sizeof(Header);
114 ctx.size = _stackSize -
sizeof(Header);
115 ctx.sp = block_start + ctx.size;
116 #if defined(BOOST_USE_VALGRIND) 117 ctx.valgrind_stack_id = VALGRIND_STACK_REGISTER(ctx.sp, block_start);
122 template <
typename STACK_TRAITS>
127 #if defined(BOOST_USE_VALGRIND) 128 VALGRIND_STACK_DEREGISTER(ctx.valgrind_stack_id);
130 if (isManaged(ctx)) {
133 _freeBlocks[++_freeBlockIndex] = blockIndex(ctx);
136 delete[] (
char*)getHeader(ctx);
138 --_numHeapAllocatedBlocks;
139 assert(_numHeapAllocatedBlocks >= 0);
143 template <
typename STACK_TRAITS>
146 return _size - _freeBlockIndex - 1;
149 template <
typename STACK_TRAITS>
152 return _numHeapAllocatedBlocks;
155 template <
typename STACK_TRAITS>
158 return _freeBlockIndex == _size-1;
161 template <
typename STACK_TRAITS>
164 return _freeBlockIndex == -1;
167 template <
typename STACK_TRAITS>
171 return reinterpret_cast<Header*>(reinterpret_cast<char*>(ctx.sp) - ctx.size -
sizeof(Header));
174 template <
typename STACK_TRAITS>
175 bool CoroutinePoolAllocator<STACK_TRAITS>::isManaged(
const boost::context::stack_context& ctx)
const 177 return blockIndex(ctx) != -1;
180 template <
typename STACK_TRAITS>
181 int CoroutinePoolAllocator<STACK_TRAITS>::blockIndex(
const boost::context::stack_context& ctx)
const 183 return getHeader(ctx)->_pos;
Definition: quantum_spinlock.h:71
STACK_TRAITS traits
Definition: quantum_coroutine_pool_allocator.h:46
Definition: quantum_buffer_impl.h:22
virtual ~CoroutinePoolAllocator()
Definition: quantum_coroutine_pool_allocator_impl.h:83
void deallocate(const boost::context::stack_context &ctx)
Definition: quantum_coroutine_pool_allocator_impl.h:123
Definition: quantum_stl_impl.h:23
Provides fast (quasi zero-time) in-place allocation for coroutines. Coroutine stacks are pre-allocate...
Definition: quantum_coroutine_pool_allocator.h:40
bool isEmpty() const
Definition: quantum_coroutine_pool_allocator_impl.h:162
CoroutinePoolAllocator(index_type size)
Definition: quantum_coroutine_pool_allocator_impl.h:32
bool isFull() const
Definition: quantum_coroutine_pool_allocator_impl.h:156
size_t allocatedBlocks() const
Definition: quantum_coroutine_pool_allocator_impl.h:144
size_t allocatedHeapBlocks() const
Definition: quantum_coroutine_pool_allocator_impl.h:150
CoroutinePoolAllocator & operator=(const this_type &)=delete
uint16_t index_type
Definition: quantum_coroutine_pool_allocator.h:45
boost::context::stack_context allocate()
Definition: quantum_coroutine_pool_allocator_impl.h:93