From f5b4cc7e32ad1171342e528fa8c1fa0c6f7a4bb9 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 23 Feb 2023 15:33:07 -0500 Subject: [PATCH] Merge bitcoin/bitcoin#16195: util: Use void* throughout support/lockedpool.h f36d1d5b8934aac60d3097047ecedeb58bae2185 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 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 f36d1d5b8934aac60d3097047ecedeb58bae2185 theStack: Code-review ACK f36d1d5b8934aac60d3097047ecedeb58bae2185 jonatack: ACK f36d1d5b8934aac60d3097047ecedeb58bae2185 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 --- src/support/lockedpool.cpp | 18 ++++++++++-------- src/support/lockedpool.h | 10 +++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index edb381042b..14ad4782d7 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -27,6 +27,7 @@ #include #include #endif +#include LockedPoolManager* LockedPoolManager::_instance = nullptr; @@ -43,12 +44,12 @@ static inline size_t align_up(size_t x, size_t align) // Implementation: Arena Arena::Arena(void *base_in, size_t size_in, size_t alignment_in): - base(static_cast(base_in)), end(static_cast(base_in) + size_in), alignment(alignment_in) + base(base_in), end(static_cast(base_in) + size_in), alignment(alignment_in) { // Start with one free chunk that covers the entire arena auto it = size_to_free_chunk.emplace(size_in, base); chunks_free.emplace(base, it); - chunks_free_end.emplace(base + size_in, it); + chunks_free_end.emplace(static_cast(base) + size_in, it); } Arena::~Arena() @@ -74,8 +75,9 @@ void* Arena::alloc(size_t size) // Create the used-chunk, taking its space from the end of the free-chunk const size_t size_remaining = size_ptr_it->first - size; - auto allocated = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first; - chunks_free_end.erase(size_ptr_it->second + size_ptr_it->first); + char* const free_chunk = static_cast(size_ptr_it->second); + auto allocated = chunks_used.emplace(free_chunk + size_remaining, size).first; + chunks_free_end.erase(free_chunk + size_ptr_it->first); if (size_ptr_it->first == size) { // whole chunk is used up chunks_free.erase(size_ptr_it->second); @@ -83,11 +85,11 @@ void* Arena::alloc(size_t size) // still some memory left in the chunk auto it_remaining = size_to_free_chunk.emplace(size_remaining, size_ptr_it->second); chunks_free[size_ptr_it->second] = it_remaining; - chunks_free_end.emplace(size_ptr_it->second + size_remaining, it_remaining); + chunks_free_end.emplace(free_chunk + size_remaining, it_remaining); } size_to_free_chunk.erase(size_ptr_it); - return reinterpret_cast(allocated->first); + return allocated->first; } void Arena::free(void *ptr) @@ -98,11 +100,11 @@ void Arena::free(void *ptr) } // Remove chunk from used map - auto i = chunks_used.find(static_cast(ptr)); + auto i = chunks_used.find(ptr); if (i == chunks_used.end()) { throw std::runtime_error("Arena: invalid or double free"); } - std::pair freed = *i; + auto freed = std::make_pair(static_cast(i->first), i->second); chunks_used.erase(i); // coalesce freed with previous chunk diff --git a/src/support/lockedpool.h b/src/support/lockedpool.h index 03e4e371a3..1aaa76009d 100644 --- a/src/support/lockedpool.h +++ b/src/support/lockedpool.h @@ -89,23 +89,23 @@ public: */ bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; } private: - typedef std::multimap SizeToChunkSortedMap; + typedef std::multimap SizeToChunkSortedMap; /** Map to enable O(log(n)) best-fit allocation, as it's sorted by size */ SizeToChunkSortedMap size_to_free_chunk; - typedef std::unordered_map ChunkToSizeMap; + typedef std::unordered_map ChunkToSizeMap; /** Map from begin of free chunk to its node in size_to_free_chunk */ ChunkToSizeMap chunks_free; /** Map from end of free chunk to its node in size_to_free_chunk */ ChunkToSizeMap chunks_free_end; /** Map from begin of used chunk to its size */ - std::unordered_map chunks_used; + std::unordered_map chunks_used; /** Base address of arena */ - char* base; + void* base; /** End address of arena */ - char* end; + void* end; /** Minimum chunk alignment */ size_t alignment; };