Skip to content

Commit c033720

Browse files
committed
Merge bitcoin/bitcoin#16195: util: Use void* throughout support/lockedpool.h
f36d1d5 Use void* throughout support/lockedpool.h (Jeffrey Czyz) Pull request description: 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. Changes to this code are covered by src/test/allocator_tests.cpp. ACKs for top commit: achow101: ACK f36d1d5 theStack: Code-review ACK f36d1d5 jonatack: ACK f36d1d5 review, debug build, unit tests, checked clang 15 raises "error: arithmetic on a pointer to void" without the conversions here from the generic void* pointer back to char* Tree-SHA512: f9074e6d29ef78c795a512a6e00e9b591e2ff34165d09b73eae9eef25098c59e543c194346fcd4e83185a39c430d43744b6f7f9d1728a132843c67bd27ea5189
2 parents b7702bd + f36d1d5 commit c033720

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
@@ -26,6 +26,7 @@
2626
#include <iomanip>
2727
#include <iostream>
2828
#endif
29+
#include <utility>
2930

3031
LockedPoolManager* LockedPoolManager::_instance = nullptr;
3132

@@ -42,12 +43,12 @@ static inline size_t align_up(size_t x, size_t align)
4243
// Implementation: Arena
4344

4445
Arena::Arena(void *base_in, size_t size_in, size_t alignment_in):
45-
base(static_cast<char*>(base_in)), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
46+
base(base_in), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
4647
{
4748
// Start with one free chunk that covers the entire arena
4849
auto it = size_to_free_chunk.emplace(size_in, base);
4950
chunks_free.emplace(base, it);
50-
chunks_free_end.emplace(base + size_in, it);
51+
chunks_free_end.emplace(static_cast<char*>(base) + size_in, it);
5152
}
5253

5354
Arena::~Arena()
@@ -73,20 +74,21 @@ void* Arena::alloc(size_t size)
7374

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

89-
return reinterpret_cast<void*>(allocated->first);
91+
return allocated->first;
9092
}
9193

9294
void Arena::free(void *ptr)
@@ -97,11 +99,11 @@ void Arena::free(void *ptr)
9799
}
98100

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

107109
// 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)