QuantumLibrary
quantum_coroutine_pool_allocator.h
1 /*
2 ** Copyright 2018 Bloomberg Finance L.P.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 #ifndef QUANUM_COROUTINE_POOL_ALLOCATOR
17 #define QUANUM_COROUTINE_POOL_ALLOCATOR
18 
19 #include <memory>
20 #include <assert.h>
21 #include <limits>
22 #include <type_traits>
23 #include <utility>
24 #include <quantum/quantum_spinlock.h>
25 #include <boost/context/stack_context.hpp>
26 
27 namespace Bloomberg {
28 namespace quantum {
29 
30 //==============================================================================
31 // struct CoroutinePoolAllocator
32 //==============================================================================
39 template <typename STACK_TRAITS>
41 {
42  //------------------------------ Typedefs ----------------------------------
44  typedef size_t size_type;
45  typedef uint16_t index_type;
46  typedef STACK_TRAITS traits;
47 
48  //------------------------------- Methods ----------------------------------
50  CoroutinePoolAllocator(const this_type&) = delete;
52  CoroutinePoolAllocator& operator=(const this_type&) = delete;
54  virtual ~CoroutinePoolAllocator();
55 
56  // Accessors
57  boost::context::stack_context allocate();
58  void deallocate(const boost::context::stack_context& ctx);
59  size_t allocatedBlocks() const;
60  size_t allocatedHeapBlocks() const;
61  bool isFull() const;
62  bool isEmpty() const;
63 
64 private:
65  struct Header {
66  int _pos;
67  };
68 
69  int blockIndex(const boost::context::stack_context& ctx) const;
70  bool isManaged(const boost::context::stack_context& ctx) const;
71  Header* getHeader(const boost::context::stack_context& ctx) const;
72 
73  //------------------------------- Members ----------------------------------
74  index_type _size;
75  Header** _blocks;
76  index_type* _freeBlocks;
77  ssize_t _freeBlockIndex;
78  size_t _numHeapAllocatedBlocks;
79  size_t _stackSize;
80  mutable SpinLock _spinlock;
81 };
82 
83 template <typename STACK_TRAITS>
85 {
86  typedef std::false_type default_constructor;
87 
88  CoroutinePoolAllocatorProxy(uint16_t size) : _alloc(new CoroutinePoolAllocator<STACK_TRAITS>(size))
89  {
90  if (!_alloc) {
91  throw std::bad_alloc();
92  }
93  }
94  // Accessors
95  boost::context::stack_context allocate() { return _alloc->allocate(); }
96  void deallocate(const boost::context::stack_context& ctx) { return _alloc->deallocate(ctx); }
97  size_t allocatedBlocks() const { return _alloc->allocatedBlocks(); }
98  size_t allocatedHeapBlocks() const { return _alloc->allocatedHeapBlocks(); }
99  bool isFull() const { return _alloc->isFull(); }
100  bool isEmpty() const { return _alloc->isEmpty(); }
101 private:
102  std::shared_ptr<CoroutinePoolAllocator<STACK_TRAITS>> _alloc;
103 };
104 
105 }} //namespaces
106 
107 #include <quantum/impl/quantum_coroutine_pool_allocator_impl.h>
108 
109 
110 #endif //QUANUM_COROUTINE_POOL_ALLOCATOR
Definition: quantum_coroutine_pool_allocator.h:84
STACK_TRAITS traits
Definition: quantum_coroutine_pool_allocator.h:46
Definition: quantum_buffer_impl.h:22
bool isEmpty() const
Definition: quantum_coroutine_pool_allocator.h:100
std::false_type default_constructor
Definition: quantum_coroutine_pool_allocator.h:86
virtual ~CoroutinePoolAllocator()
Definition: quantum_coroutine_pool_allocator_impl.h:83
CoroutinePoolAllocator< STACK_TRAITS > this_type
Definition: quantum_coroutine_pool_allocator.h:43
void deallocate(const boost::context::stack_context &ctx)
Definition: quantum_coroutine_pool_allocator_impl.h:123
bool isFull() const
Definition: quantum_coroutine_pool_allocator.h:99
size_t allocatedHeapBlocks() const
Definition: quantum_coroutine_pool_allocator.h:98
boost::context::stack_context allocate()
Definition: quantum_coroutine_pool_allocator.h:95
Provides fast (quasi zero-time) in-place allocation for coroutines. Coroutine stacks are pre-allocate...
Definition: quantum_coroutine_pool_allocator.h:40
size_t size_type
Definition: quantum_coroutine_pool_allocator.h:44
CoroutinePoolAllocatorProxy(uint16_t size)
Definition: quantum_coroutine_pool_allocator.h:88
bool isEmpty() const
Definition: quantum_coroutine_pool_allocator_impl.h:162
void deallocate(const boost::context::stack_context &ctx)
Definition: quantum_coroutine_pool_allocator.h:96
size_t allocatedBlocks() const
Definition: quantum_coroutine_pool_allocator.h:97
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