14
14
namespace osrm ::util
15
15
{
16
16
17
- template <typename T>
18
- class PoolAllocator ;
19
-
20
- template <typename T>
21
17
class MemoryManager
22
18
{
23
19
private:
24
20
constexpr static size_t MIN_ITEMS_IN_BLOCK = 1024 ;
21
+
25
22
public:
26
23
static std::shared_ptr<MemoryManager> instance ()
27
24
{
@@ -33,42 +30,45 @@ class MemoryManager
33
30
return instance;
34
31
}
35
32
33
+ template <typename T>
36
34
T *allocate (std::size_t n)
37
35
{
38
- size_t free_list_index = get_next_power_of_two_exponent (n);
36
+ size_t free_list_index = get_next_power_of_two_exponent (n * sizeof (T) );
39
37
auto &free_list = free_lists_[free_list_index];
40
38
const auto items_in_block = 1u << free_list_index;
41
39
if (free_list.empty ())
42
40
{
43
41
// Check if there is space in current block
44
42
if (current_block_left_items_ < items_in_block)
45
43
{
46
- allocate_block (items_in_block);
44
+ allocate_block<T> (items_in_block);
47
45
}
48
46
49
47
free_list.push_back (current_block_ptr_);
50
48
current_block_left_items_ -= items_in_block;
51
- current_block_ptr_ += items_in_block;
49
+ current_block_ptr_ += items_in_block * sizeof (T) ;
52
50
}
53
- auto ptr = free_list.back ();
51
+ auto ptr = static_cast <T*>( free_list.back () );
54
52
free_list.pop_back ();
55
53
return ptr;
56
54
}
57
55
56
+ template <typename T>
58
57
void deallocate (T *p, std::size_t n) noexcept
59
58
{
60
- size_t free_list_index = get_next_power_of_two_exponent (n);
59
+ size_t free_list_index = get_next_power_of_two_exponent (n * sizeof (T) );
61
60
free_lists_[free_list_index].push_back (p);
62
61
}
63
62
64
63
~MemoryManager ()
65
64
{
66
- // std::cerr << "~MemoryManager()" << std::endl;
65
+ std::cerr << " ~MemoryManager()" << std::endl;
67
66
for (auto block : blocks_)
68
67
{
69
68
std::free (block);
70
69
}
71
70
}
71
+
72
72
private:
73
73
MemoryManager () = default ;
74
74
MemoryManager (const MemoryManager &) = delete ;
@@ -80,25 +80,26 @@ class MemoryManager
80
80
return (sizeof (size_t ) * 8 ) - std::countl_zero (n - 1 );
81
81
}
82
82
83
+ template <typename T>
83
84
void allocate_block (size_t items_in_block)
84
85
{
85
86
items_in_block = std::max (items_in_block, MIN_ITEMS_IN_BLOCK);
86
87
87
88
size_t block_size = items_in_block * sizeof (T);
88
- T *block = static_cast <T *>( std::malloc (block_size) );
89
+ void *block = std::malloc (block_size);
89
90
if (!block)
90
91
{
91
92
throw std::bad_alloc ();
92
93
}
93
94
total_allocated_ += block_size;
94
95
blocks_.push_back (block);
95
- current_block_ptr_ = block;
96
+ current_block_ptr_ = static_cast < uint8_t *>( block) ;
96
97
current_block_left_items_ = items_in_block;
97
98
}
98
99
99
- std::array<std::vector<T *>, 32 > free_lists_;
100
- std::vector<T *> blocks_;
101
- T *current_block_ptr_ = nullptr ;
100
+ std::array<std::vector<void *>, 32 > free_lists_;
101
+ std::vector<void *> blocks_;
102
+ uint8_t *current_block_ptr_ = nullptr ;
102
103
size_t current_block_left_items_ = 0 ;
103
104
104
105
size_t total_allocated_ = 0 ;
@@ -110,10 +111,10 @@ class PoolAllocator
110
111
public:
111
112
using value_type = T;
112
113
113
- PoolAllocator () noexcept : pool(MemoryManager<T> ::instance()) {};
114
+ PoolAllocator () noexcept : pool(MemoryManager::instance()) {};
114
115
115
116
template <typename U>
116
- PoolAllocator (const PoolAllocator<U> &) noexcept : pool(MemoryManager<T> ::instance()) {}
117
+ PoolAllocator (const PoolAllocator<U> &) noexcept : pool(MemoryManager::instance()) {}
117
118
118
119
template <typename U>
119
120
struct rebind
@@ -123,25 +124,26 @@ class PoolAllocator
123
124
124
125
T *allocate (std::size_t n)
125
126
{
126
- return pool->allocate (n);
127
+ return pool->allocate <T> (n);
127
128
}
128
129
129
130
void deallocate (T *p, std::size_t n) noexcept
130
131
{
131
- pool->deallocate (p, n);
132
+ pool->deallocate <T> (p, n);
132
133
}
133
134
134
- ~PoolAllocator () = default ;
135
+ ~PoolAllocator () {
136
+ std::cerr << " ~PoolAllocator()" << std::endl;
137
+ }
135
138
136
139
PoolAllocator (const PoolAllocator &) = default ;
137
140
PoolAllocator &operator =(const PoolAllocator &) = default ;
138
141
PoolAllocator (PoolAllocator &&) noexcept = default ;
139
142
PoolAllocator &operator =(PoolAllocator &&) noexcept = default ;
140
143
141
144
private:
142
- std::shared_ptr<MemoryManager<T> > pool;
145
+ std::shared_ptr<MemoryManager> pool;
143
146
};
144
-
145
147
template <typename T, typename U>
146
148
bool operator ==(const PoolAllocator<T> &, const PoolAllocator<U> &)
147
149
{
0 commit comments