Skip to content

Commit f36d1d5

Browse files
committed
Use void* throughout support/lockedpool.h
Replace uses of char* with void* in Arena's member variables. Instead, cast to char* where needed in the implementation. Certain compiler environments disallow std::hash<char*> specializations to prevent hashing the pointer's value instead of the string contents. Thus, compilation fails when std::unordered_map is keyed by char*. Explicitly using void* is a workaround in such environments. For consistency, void* is used throughout all member variables similarly to the public interface.
1 parent b7bc9b8 commit f36d1d5

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

src/support/lockedpool.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <iomanip>
2828
#include <iostream>
2929
#endif
30+
#include <utility>
3031

3132
LockedPoolManager* LockedPoolManager::_instance = nullptr;
3233
std::once_flag LockedPoolManager::init_flag;
@@ -44,12 +45,12 @@ static inline size_t align_up(size_t x, size_t align)
4445
// Implementation: Arena
4546

4647
Arena::Arena(void *base_in, size_t size_in, size_t alignment_in):
47-
base(static_cast<char*>(base_in)), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
48+
base(base_in), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
4849
{
4950
// Start with one free chunk that covers the entire arena
5051
auto it = size_to_free_chunk.emplace(size_in, base);
5152
chunks_free.emplace(base, it);
52-
chunks_free_end.emplace(base + size_in, it);
53+
chunks_free_end.emplace(static_cast<char*>(base) + size_in, it);
5354
}
5455

5556
Arena::~Arena()
@@ -75,20 +76,21 @@ void* Arena::alloc(size_t size)
7576

7677
// Create the used-chunk, taking its space from the end of the free-chunk
7778
const size_t size_remaining = size_ptr_it->first - size;
78-
auto allocated = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first;
79-
chunks_free_end.erase(size_ptr_it->second + size_ptr_it->first);
79+
char* const free_chunk = static_cast<char*>(size_ptr_it->second);
80+
auto allocated = chunks_used.emplace(free_chunk + size_remaining, size).first;
81+
chunks_free_end.erase(free_chunk + size_ptr_it->first);
8082
if (size_ptr_it->first == size) {
8183
// whole chunk is used up
8284
chunks_free.erase(size_ptr_it->second);
8385
} else {
8486
// still some memory left in the chunk
8587
auto it_remaining = size_to_free_chunk.emplace(size_remaining, size_ptr_it->second);
8688
chunks_free[size_ptr_it->second] = it_remaining;
87-
chunks_free_end.emplace(size_ptr_it->second + size_remaining, it_remaining);
89+
chunks_free_end.emplace(free_chunk + size_remaining, it_remaining);
8890
}
8991
size_to_free_chunk.erase(size_ptr_it);
9092

91-
return reinterpret_cast<void*>(allocated->first);
93+
return allocated->first;
9294
}
9395

9496
void Arena::free(void *ptr)
@@ -99,11 +101,11 @@ void Arena::free(void *ptr)
99101
}
100102

101103
// Remove chunk from used map
102-
auto i = chunks_used.find(static_cast<char*>(ptr));
104+
auto i = chunks_used.find(ptr);
103105
if (i == chunks_used.end()) {
104106
throw std::runtime_error("Arena: invalid or double free");
105107
}
106-
std::pair<char*, size_t> freed = *i;
108+
auto freed = std::make_pair(static_cast<char*>(i->first), i->second);
107109
chunks_used.erase(i);
108110

109111
// coalesce freed with previous chunk

src/support/lockedpool.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,23 @@ class Arena
8989
*/
9090
bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; }
9191
private:
92-
typedef std::multimap<size_t, char*> SizeToChunkSortedMap;
92+
typedef std::multimap<size_t, void*> SizeToChunkSortedMap;
9393
/** Map to enable O(log(n)) best-fit allocation, as it's sorted by size */
9494
SizeToChunkSortedMap size_to_free_chunk;
9595

96-
typedef std::unordered_map<char*, SizeToChunkSortedMap::const_iterator> ChunkToSizeMap;
96+
typedef std::unordered_map<void*, SizeToChunkSortedMap::const_iterator> ChunkToSizeMap;
9797
/** Map from begin of free chunk to its node in size_to_free_chunk */
9898
ChunkToSizeMap chunks_free;
9999
/** Map from end of free chunk to its node in size_to_free_chunk */
100100
ChunkToSizeMap chunks_free_end;
101101

102102
/** Map from begin of used chunk to its size */
103-
std::unordered_map<char*, size_t> chunks_used;
103+
std::unordered_map<void*, size_t> chunks_used;
104104

105105
/** Base address of arena */
106-
char* base;
106+
void* base;
107107
/** End address of arena */
108-
char* end;
108+
void* end;
109109
/** Minimum chunk alignment */
110110
size_t alignment;
111111
};

0 commit comments

Comments
 (0)