diff options
Diffstat (limited to 'src/alloc/mem_pool/mem_pool.cpp')
-rw-r--r-- | src/alloc/mem_pool/mem_pool.cpp | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/src/alloc/mem_pool/mem_pool.cpp b/src/alloc/mem_pool/mem_pool.cpp deleted file mode 100644 index 770622149..000000000 --- a/src/alloc/mem_pool/mem_pool.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* Pooling Allocator -* (C) 1999-2008 Jack Lloyd -* 2005 Matthew Gregan -* 2005-2006 Matt Johnston -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/mem_pool.h> -#include <botan/internal/rounding.h> -#include <botan/mem_ops.h> -#include <algorithm> -#include <exception> - -namespace Botan { - -/* -* Memory_Block Constructor -*/ -Pooling_Allocator::Memory_Block::Memory_Block(void* buf) - { - buffer = static_cast<byte*>(buf); - bitmap = 0; - buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE); - } - -/* -* See if ptr is contained by this block -*/ -bool Pooling_Allocator::Memory_Block::contains(void* ptr, - size_t length) const - { - return ((buffer <= ptr) && - (buffer_end >= static_cast<byte*>(ptr) + length * BLOCK_SIZE)); - } - -/* -* Allocate some memory, if possible -*/ -byte* Pooling_Allocator::Memory_Block::alloc(size_t n) - { - if(n == 0 || n > BITMAP_SIZE) - return 0; - - if(n == BITMAP_SIZE) - { - if(bitmap) - return nullptr; - else - { - bitmap = ~bitmap; - return buffer; - } - } - - bitmap_type mask = (static_cast<bitmap_type>(1) << n) - 1; - size_t offset = 0; - - while(bitmap & mask) - { - mask <<= 1; - ++offset; - - if((bitmap & mask) == 0) - break; - if(mask >> 63) - break; - } - - if(bitmap & mask) - return nullptr; - - bitmap |= mask; - return buffer + offset * BLOCK_SIZE; - } - -/* -* Mark this memory as free, if we own it -*/ -void Pooling_Allocator::Memory_Block::free(void* ptr, size_t blocks) - { - clear_mem(static_cast<byte*>(ptr), blocks * BLOCK_SIZE); - - const size_t offset = (static_cast<byte*>(ptr) - buffer) / BLOCK_SIZE; - - if(offset == 0 && blocks == BITMAP_SIZE) - bitmap = ~bitmap; - else - { - for(size_t j = 0; j != blocks; ++j) - bitmap &= ~(static_cast<bitmap_type>(1) << (j+offset)); - } - } - -/* -* Pooling_Allocator Constructor -*/ -Pooling_Allocator::Pooling_Allocator() - { - last_used = blocks.begin(); - } - -/* -* Pooling_Allocator Destructor -*/ -Pooling_Allocator::~Pooling_Allocator() - { - if(blocks.size()) - throw Invalid_State("Pooling_Allocator: Never released memory"); - } - -/* -* Free all remaining memory -*/ -void Pooling_Allocator::destroy() - { - std::lock_guard<std::mutex> lock(mutex); - - blocks.clear(); - - for(size_t j = 0; j != allocated.size(); ++j) - dealloc_block(allocated[j].first, allocated[j].second); - allocated.clear(); - } - -/* -* Allocation -*/ -void* Pooling_Allocator::allocate(size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - std::lock_guard<std::mutex> lock(mutex); - - if(n <= BITMAP_SIZE * BLOCK_SIZE) - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - byte* mem = allocate_blocks(block_no); - if(mem) - return mem; - - get_more_core(BOTAN_MEM_POOL_CHUNK_SIZE); - - mem = allocate_blocks(block_no); - if(mem) - return mem; - - throw Memory_Exhaustion(); - } - - void* new_buf = alloc_block(n); - if(new_buf) - return new_buf; - - throw Memory_Exhaustion(); - } - -/* -* Deallocation -*/ -void Pooling_Allocator::deallocate(void* ptr, size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - if(ptr == nullptr && n == 0) - return; - - std::lock_guard<std::mutex> lock(mutex); - - if(n > BITMAP_SIZE * BLOCK_SIZE) - dealloc_block(ptr, n); - else - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - auto i = std::lower_bound(blocks.begin(), blocks.end(), - Memory_Block(ptr)); - - if(i == blocks.end() || !i->contains(ptr, block_no)) - throw Invalid_State("Pointer released to the wrong allocator"); - - i->free(ptr, block_no); - } - } - -/* -* Try to get some memory from an existing block -*/ -byte* Pooling_Allocator::allocate_blocks(size_t n) - { - if(blocks.empty()) - return nullptr; - - auto i = last_used; - - do - { - byte* mem = i->alloc(n); - if(mem) - { - last_used = i; - return mem; - } - - ++i; - if(i == blocks.end()) - i = blocks.begin(); - } - while(i != last_used); - - return nullptr; - } - -/* -* Allocate more memory for the pool -*/ -void Pooling_Allocator::get_more_core(size_t in_bytes) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - const size_t TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE; - - // upper bound on allocation is 1 MiB - in_bytes = std::min<size_t>(in_bytes, 1024 * 1024); - - const size_t in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE; - const size_t to_allocate = in_blocks * TOTAL_BLOCK_SIZE; - - void* ptr = alloc_block(to_allocate); - if(ptr == nullptr) - throw Memory_Exhaustion(); - - allocated.push_back(std::make_pair(ptr, to_allocate)); - - for(size_t j = 0; j != in_blocks; ++j) - { - byte* byte_ptr = static_cast<byte*>(ptr); - blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE)); - } - - std::sort(blocks.begin(), blocks.end()); - last_used = std::lower_bound(blocks.begin(), blocks.end(), - Memory_Block(ptr)); - } - -} |