mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
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.
This commit is contained in:
parent
b7bc9b8330
commit
f36d1d5b89
2 changed files with 15 additions and 13 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
LockedPoolManager* LockedPoolManager::_instance = nullptr;
|
LockedPoolManager* LockedPoolManager::_instance = nullptr;
|
||||||
std::once_flag LockedPoolManager::init_flag;
|
std::once_flag LockedPoolManager::init_flag;
|
||||||
|
@ -44,12 +45,12 @@ static inline size_t align_up(size_t x, size_t align)
|
||||||
// Implementation: Arena
|
// Implementation: Arena
|
||||||
|
|
||||||
Arena::Arena(void *base_in, size_t size_in, size_t alignment_in):
|
Arena::Arena(void *base_in, size_t size_in, size_t alignment_in):
|
||||||
base(static_cast<char*>(base_in)), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
|
base(base_in), end(static_cast<char*>(base_in) + size_in), alignment(alignment_in)
|
||||||
{
|
{
|
||||||
// Start with one free chunk that covers the entire arena
|
// Start with one free chunk that covers the entire arena
|
||||||
auto it = size_to_free_chunk.emplace(size_in, base);
|
auto it = size_to_free_chunk.emplace(size_in, base);
|
||||||
chunks_free.emplace(base, it);
|
chunks_free.emplace(base, it);
|
||||||
chunks_free_end.emplace(base + size_in, it);
|
chunks_free_end.emplace(static_cast<char*>(base) + size_in, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
Arena::~Arena()
|
Arena::~Arena()
|
||||||
|
@ -75,8 +76,9 @@ void* Arena::alloc(size_t size)
|
||||||
|
|
||||||
// Create the used-chunk, taking its space from the end of the free-chunk
|
// Create the used-chunk, taking its space from the end of the free-chunk
|
||||||
const size_t size_remaining = size_ptr_it->first - size;
|
const size_t size_remaining = size_ptr_it->first - size;
|
||||||
auto allocated = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first;
|
char* const free_chunk = static_cast<char*>(size_ptr_it->second);
|
||||||
chunks_free_end.erase(size_ptr_it->second + size_ptr_it->first);
|
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) {
|
if (size_ptr_it->first == size) {
|
||||||
// whole chunk is used up
|
// whole chunk is used up
|
||||||
chunks_free.erase(size_ptr_it->second);
|
chunks_free.erase(size_ptr_it->second);
|
||||||
|
@ -84,11 +86,11 @@ void* Arena::alloc(size_t size)
|
||||||
// still some memory left in the chunk
|
// still some memory left in the chunk
|
||||||
auto it_remaining = size_to_free_chunk.emplace(size_remaining, size_ptr_it->second);
|
auto it_remaining = size_to_free_chunk.emplace(size_remaining, size_ptr_it->second);
|
||||||
chunks_free[size_ptr_it->second] = it_remaining;
|
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);
|
size_to_free_chunk.erase(size_ptr_it);
|
||||||
|
|
||||||
return reinterpret_cast<void*>(allocated->first);
|
return allocated->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arena::free(void *ptr)
|
void Arena::free(void *ptr)
|
||||||
|
@ -99,11 +101,11 @@ void Arena::free(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove chunk from used map
|
// Remove chunk from used map
|
||||||
auto i = chunks_used.find(static_cast<char*>(ptr));
|
auto i = chunks_used.find(ptr);
|
||||||
if (i == chunks_used.end()) {
|
if (i == chunks_used.end()) {
|
||||||
throw std::runtime_error("Arena: invalid or double free");
|
throw std::runtime_error("Arena: invalid or double free");
|
||||||
}
|
}
|
||||||
std::pair<char*, size_t> freed = *i;
|
auto freed = std::make_pair(static_cast<char*>(i->first), i->second);
|
||||||
chunks_used.erase(i);
|
chunks_used.erase(i);
|
||||||
|
|
||||||
// coalesce freed with previous chunk
|
// coalesce freed with previous chunk
|
||||||
|
|
|
@ -89,23 +89,23 @@ public:
|
||||||
*/
|
*/
|
||||||
bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; }
|
bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; }
|
||||||
private:
|
private:
|
||||||
typedef std::multimap<size_t, char*> SizeToChunkSortedMap;
|
typedef std::multimap<size_t, void*> SizeToChunkSortedMap;
|
||||||
/** Map to enable O(log(n)) best-fit allocation, as it's sorted by size */
|
/** Map to enable O(log(n)) best-fit allocation, as it's sorted by size */
|
||||||
SizeToChunkSortedMap size_to_free_chunk;
|
SizeToChunkSortedMap size_to_free_chunk;
|
||||||
|
|
||||||
typedef std::unordered_map<char*, SizeToChunkSortedMap::const_iterator> ChunkToSizeMap;
|
typedef std::unordered_map<void*, SizeToChunkSortedMap::const_iterator> ChunkToSizeMap;
|
||||||
/** Map from begin of free chunk to its node in size_to_free_chunk */
|
/** Map from begin of free chunk to its node in size_to_free_chunk */
|
||||||
ChunkToSizeMap chunks_free;
|
ChunkToSizeMap chunks_free;
|
||||||
/** Map from end of free chunk to its node in size_to_free_chunk */
|
/** Map from end of free chunk to its node in size_to_free_chunk */
|
||||||
ChunkToSizeMap chunks_free_end;
|
ChunkToSizeMap chunks_free_end;
|
||||||
|
|
||||||
/** Map from begin of used chunk to its size */
|
/** Map from begin of used chunk to its size */
|
||||||
std::unordered_map<char*, size_t> chunks_used;
|
std::unordered_map<void*, size_t> chunks_used;
|
||||||
|
|
||||||
/** Base address of arena */
|
/** Base address of arena */
|
||||||
char* base;
|
void* base;
|
||||||
/** End address of arena */
|
/** End address of arena */
|
||||||
char* end;
|
void* end;
|
||||||
/** Minimum chunk alignment */
|
/** Minimum chunk alignment */
|
||||||
size_t alignment;
|
size_t alignment;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue