Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
memory_pool_allocator.h
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.sudo make instamake install
14  */
15 
16 #pragma once
17 
18 #include <memory>
19 
20 namespace utils {
21 
22 template <class T, std::size_t growSize = 1024>
23 class MemoryPool {
24  struct Block {
25  Block *next;
26  };
27 
28  class Buffer {
29  static const std::size_t blockSize = sizeof(T) > sizeof(Block)
30  ? sizeof(T)
31  : sizeof(Block);
32  uint8_t data[blockSize * growSize];
33 
34  public:
35  Buffer *const next;
36 
37  Buffer(Buffer *next) : next(next) {}
38 
39  T *getBlock(std::size_t index) {
40  return reinterpret_cast<T *>(&data[blockSize * index]);
41  }
42  };
43 
44  Block *firstFreeBlock = nullptr;
45  Buffer *firstBuffer = nullptr;
46  std::size_t bufferedBlocks = growSize;
47 
48  public:
49  MemoryPool() = default;
50  MemoryPool(MemoryPool &&memoryPool) = delete;
51  MemoryPool(const MemoryPool &memoryPool) = delete;
52  MemoryPool operator=(MemoryPool &&memoryPool) = delete;
53  MemoryPool operator=(const MemoryPool &memoryPool) = delete;
54 
55  ~MemoryPool() {
56  while (firstBuffer) {
57  Buffer *buffer = firstBuffer;
58  firstBuffer = buffer->next;
59  delete buffer;
60  }
61  }
62 
63  T *allocate() {
64  if (firstFreeBlock) {
65  Block *block = firstFreeBlock;
66  firstFreeBlock = block->next;
67  return reinterpret_cast<T *>(block);
68  }
69 
70  if (bufferedBlocks >= growSize) {
71  firstBuffer = new Buffer(firstBuffer);
72  bufferedBlocks = 0;
73  }
74 
75  return firstBuffer->getBlock(bufferedBlocks++);
76  }
77 
78  void deallocate(T *pointer) {
79  Block *block = reinterpret_cast<Block *>(pointer);
80  block->next = firstFreeBlock;
81  firstFreeBlock = block;
82  }
83 };
84 
85 template <class T, std::size_t growSize = 1024>
86 class Allocator : private MemoryPool<T, growSize> {
87 #ifdef _WIN32
88  Allocator *copyAllocator;
89  std::allocator<T> *rebindAllocator = nullptr;
90 #endif
91 
92  public:
93  typedef std::size_t size_type;
94  typedef std::ptrdiff_t difference_type;
95  typedef T *pointer;
96  typedef const T *const_pointer;
97  typedef T &reference;
98  typedef const T &const_reference;
99  typedef T value_type;
100 
101  template <class U>
102  struct rebind {
104  };
105 
106 #ifdef _WIN32
107  Allocator() = default;
108 
109  Allocator(Allocator &allocator) : copyAllocator(&allocator) {}
110 
111  template <class U>
112  Allocator(const Allocator<U, growSize> &other) {
113  if (!std::is_same<T, U>::value) rebindAllocator = new std::allocator<T>();
114  }
115 
116  ~Allocator() { delete rebindAllocator; }
117 #endif
118 
119  pointer allocate(size_type n, const void *hint = 0) {
120 #ifdef _WIN32
121  if (copyAllocator) return copyAllocator->allocate(n, hint);
122 
123  if (rebindAllocator) return rebindAllocator->allocate(n, hint);
124 #endif
125 
126  if (n != 1 || hint) throw std::bad_alloc();
127 
128  return MemoryPool<T, growSize>::allocate();
129  }
130 
131  void deallocate(pointer p, size_type n) {
132 #ifdef _WIN32
133  if (copyAllocator) {
134  copyAllocator->deallocate(p, n);
135  return;
136  }
137 
138  if (rebindAllocator) {
139  rebindAllocator->deallocate(p, n);
140  return;
141  }
142 #endif
143 
144  MemoryPool<T, growSize>::deallocate(p);
145  }
146 
147  void construct(pointer p, const_reference val) { new (p) T(val); }
148 
149  void destroy(pointer p) { p->~T(); }
150 };
151 
152 } // namespace utils
utils::Allocator
Definition: memory_pool_allocator.h:86
utils::Allocator::rebind
Definition: memory_pool_allocator.h:102
utils::MemoryPool
Definition: memory_pool_allocator.h:23