1414namespace osrm ::util
1515{
1616
17- class MemoryManager
17+ class MemoryPool
1818{
1919private:
20- constexpr static size_t MIN_ITEMS_IN_BLOCK = 1024 ;
20+ constexpr static size_t MIN_CHUNK_SIZE_BYTES = 4096 ;
2121
2222public:
23- static std::shared_ptr<MemoryManager > instance ()
23+ static std::shared_ptr<MemoryPool > instance ()
2424 {
25- static thread_local std::shared_ptr<MemoryManager > instance;
25+ static thread_local std::shared_ptr<MemoryPool > instance;
2626 if (!instance)
2727 {
28- instance = std::shared_ptr<MemoryManager >(new MemoryManager ());
28+ instance = std::shared_ptr<MemoryPool >(new MemoryPool ());
2929 }
3030 return instance;
3131 }
3232
33- // TODO: alignment!!!
3433 template <typename T>
35- T *allocate (std::size_t n )
34+ T *allocate (std::size_t items_count )
3635 {
37- size_t free_list_index = get_next_power_of_two_exponent (n * sizeof (T));
36+ size_t free_list_index = get_next_power_of_two_exponent (items_count * sizeof (T));
3837 auto &free_list = free_lists_[free_list_index];
39- const auto items_in_block = 1u << free_list_index;
4038 if (free_list.empty ())
4139 {
42- // Check if there is space in current block
43- if (current_block_left_items_ < items_in_block)
40+ const auto block_size_in_bytes = 1u << free_list_index;
41+
42+ // Check if there is space in current memory chunk
43+ if (current_chunk_left_bytes_ < block_size_in_bytes)
4444 {
45- allocate_block<T>(items_in_block );
45+ allocate_block<T>(block_size_in_bytes );
4646 }
4747
48- free_list.push_back (current_block_ptr_ );
49- current_block_left_items_ -= items_in_block ;
50- current_block_ptr_ += items_in_block * sizeof (T);
48+ free_list.push_back (current_chunk_ptr_ );
49+ current_chunk_left_bytes_ -= block_size_in_bytes ;
50+ current_chunk_ptr_ += items_count * sizeof (T);
5151 }
5252 auto ptr = static_cast <T*>(free_list.back ());
5353 free_list.pop_back ();
@@ -61,19 +61,19 @@ class MemoryManager
6161 free_lists_[free_list_index].push_back (p);
6262 }
6363
64- ~MemoryManager ()
64+ ~MemoryPool ()
6565 {
66- std::cerr << " ~MemoryManager()" << std::endl;
67- for (auto block : blocks_)
66+ for (auto chunk : chunks_)
6867 {
69- std::free (block);
68+ // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
69+ std::free (chunk);
7070 }
7171 }
7272
7373private:
74- MemoryManager () = default ;
75- MemoryManager (const MemoryManager &) = delete ;
76- MemoryManager &operator =(const MemoryManager &) = delete ;
74+ MemoryPool () = default ;
75+ MemoryPool (const MemoryPool &) = delete ;
76+ MemoryPool &operator =(const MemoryPool &) = delete ;
7777
7878 size_t get_next_power_of_two_exponent (size_t n) const
7979 {
@@ -82,26 +82,25 @@ class MemoryManager
8282 }
8383
8484 template <typename T>
85- void allocate_block (size_t items_in_block )
85+ void allocate_block (size_t bytes )
8686 {
87- items_in_block = std::max (items_in_block, MIN_ITEMS_IN_BLOCK);
88-
89- size_t block_size = items_in_block * sizeof (T);
90- void *block = std::malloc (block_size);
91- if (!block)
87+ auto chunk_size = std::max (bytes, MIN_CHUNK_SIZE_BYTES);
88+ // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
89+ void *chunk = std::malloc (chunk_size);
90+ if (!chunk)
9291 {
9392 throw std::bad_alloc ();
9493 }
95- total_allocated_ += block_size ;
96- blocks_ .push_back (block );
97- current_block_ptr_ = static_cast <uint8_t *>(block );
98- current_block_left_items_ = items_in_block ;
94+ total_allocated_ += chunk_size ;
95+ chunks_ .push_back (chunk );
96+ current_chunk_ptr_ = static_cast <uint8_t *>(chunk );
97+ current_chunk_left_bytes_ = chunk_size ;
9998 }
10099
101100 std::array<std::vector<void *>, 32 > free_lists_;
102- std::vector<void *> blocks_ ;
103- uint8_t *current_block_ptr_ = nullptr ;
104- size_t current_block_left_items_ = 0 ;
101+ std::vector<void *> chunks_ ;
102+ uint8_t *current_chunk_ptr_ = nullptr ;
103+ size_t current_chunk_left_bytes_ = 0 ;
105104
106105 size_t total_allocated_ = 0 ;
107106};
@@ -112,10 +111,10 @@ class PoolAllocator
112111public:
113112 using value_type = T;
114113
115- PoolAllocator () noexcept : pool(MemoryManager ::instance()) {};
114+ PoolAllocator () noexcept : pool(MemoryPool ::instance()) {};
116115
117116 template <typename U>
118- PoolAllocator (const PoolAllocator<U> &) noexcept : pool(MemoryManager ::instance()) {}
117+ PoolAllocator (const PoolAllocator<U> &) noexcept : pool(MemoryPool ::instance()) {}
119118
120119 template <typename U>
121120 struct rebind
@@ -133,17 +132,13 @@ class PoolAllocator
133132 pool->deallocate <T>(p, n);
134133 }
135134
136- ~PoolAllocator () {
137- std::cerr << " ~PoolAllocator()" << std::endl;
138- }
139-
140135 PoolAllocator (const PoolAllocator &) = default ;
141136 PoolAllocator &operator =(const PoolAllocator &) = default ;
142137 PoolAllocator (PoolAllocator &&) noexcept = default ;
143138 PoolAllocator &operator =(PoolAllocator &&) noexcept = default ;
144139
145140private:
146- std::shared_ptr<MemoryManager > pool;
141+ std::shared_ptr<MemoryPool > pool;
147142};
148143template <typename T, typename U>
149144bool operator ==(const PoolAllocator<T> &, const PoolAllocator<U> &)
0 commit comments