20 #ifndef MXNET_COMMON_OBJECT_POOL_H_
21 #define MXNET_COMMON_OBJECT_POOL_H_
22 #include <dmlc/logging.h>
44 template <
typename... Args>
45 T*
New(Args&&... args);
73 LinkedList* next{
nullptr};
77 LinkedList* next{
nullptr};
86 constexpr
static std::size_t kPageSize = 1 << 12;
92 LinkedList* head_{
nullptr};
96 std::vector<void*> allocated_;
106 void AllocateChunk();
113 template <
typename T>
119 template <
typename... Args>
120 static T*
New(Args&&... args);
127 static void Delete(T* ptr);
130 template <
typename T>
132 for (
auto i : allocated_) {
141 template <
typename T>
142 template <
typename... Args>
146 std::lock_guard<std::mutex>
lock{m_};
147 if (head_->next ==
nullptr) {
153 return new (
static_cast<void*
>(ret)) T(std::forward<Args>(args)...);
156 template <
typename T>
159 auto linked_list_ptr =
reinterpret_cast<LinkedList*
>(ptr);
161 std::lock_guard<std::mutex>
lock{m_};
162 linked_list_ptr->next = head_;
163 head_ = linked_list_ptr;
167 template <
typename T>
169 return _GetSharedRef().get();
172 template <
typename T>
174 static std::shared_ptr<ObjectPool<T> > inst_ptr(
new ObjectPool<T>());
178 template <
typename T>
183 template <
typename T>
184 void ObjectPool<T>::AllocateChunk() {
185 static_assert(
sizeof(LinkedList) <= kPageSize,
"Object too big.");
186 static_assert(
sizeof(LinkedList) %
alignof(LinkedList) == 0,
"ObjectPooll Invariant");
187 static_assert(
alignof(LinkedList) %
alignof(T) == 0,
"ObjectPooll Invariant");
188 static_assert(kPageSize %
alignof(LinkedList) == 0,
"ObjectPooll Invariant");
191 new_chunk_ptr = _aligned_malloc(kPageSize, kPageSize);
192 CHECK(new_chunk_ptr !=
nullptr) <<
"Allocation failed";
194 int ret = posix_memalign(&new_chunk_ptr, kPageSize, kPageSize);
195 CHECK_EQ(ret, 0) <<
"Allocation failed";
197 allocated_.emplace_back(new_chunk_ptr);
198 auto new_chunk =
static_cast<LinkedList*
>(new_chunk_ptr);
199 auto size = kPageSize /
sizeof(LinkedList);
200 for (std::size_t i = 0; i < size - 1; ++i) {
201 new_chunk[i].next = &new_chunk[i + 1];
203 new_chunk[size - 1].next = head_;
207 template <
typename T>
208 template <
typename... Args>
213 template <
typename T>
220 #endif // MXNET_COMMON_OBJECT_POOL_H_