diff options
Diffstat (limited to 'comm/third_party/botan/src/lib/utils/locking_allocator')
3 files changed, 132 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/utils/locking_allocator/info.txt b/comm/third_party/botan/src/lib/utils/locking_allocator/info.txt new file mode 100644 index 0000000000..5d7a2ba83e --- /dev/null +++ b/comm/third_party/botan/src/lib/utils/locking_allocator/info.txt @@ -0,0 +1,12 @@ +<defines> +LOCKING_ALLOCATOR -> 20131128 +</defines> + +<os_features> +posix1 +virtual_lock +</os_features> + +<requires> +mem_pool +</requires> diff --git a/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.cpp b/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.cpp new file mode 100644 index 0000000000..1c10c362b6 --- /dev/null +++ b/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.cpp @@ -0,0 +1,75 @@ +/* +* Mlock Allocator +* (C) 2012,2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/locking_allocator.h> +#include <botan/internal/os_utils.h> +#include <botan/internal/mem_pool.h> + +namespace Botan { + +void* mlock_allocator::allocate(size_t num_elems, size_t elem_size) + { + if(!m_pool) + return nullptr; + + const size_t n = num_elems * elem_size; + if(n / elem_size != num_elems) + return nullptr; // overflow! + + return m_pool->allocate(n); + } + +bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) noexcept + { + if(!m_pool) + return false; + + size_t n = num_elems * elem_size; + + /* + We return nullptr in allocate if there was an overflow, so if an + overflow occurs here we know the pointer was not allocated by this pool. + */ + if(n / elem_size != num_elems) + return false; + + return m_pool->deallocate(p, n); + } + +mlock_allocator::mlock_allocator() + { + const size_t mem_to_lock = OS::get_memory_locking_limit(); + const size_t page_size = OS::system_page_size(); + + if(mem_to_lock > 0 && mem_to_lock % page_size == 0) + { + m_locked_pages = OS::allocate_locked_pages(mem_to_lock / page_size); + + if(m_locked_pages.size() > 0) + { + m_pool.reset(new Memory_Pool(m_locked_pages, page_size)); + } + } + } + +mlock_allocator::~mlock_allocator() + { + if(m_pool) + { + m_pool.reset(); + // OS::free_locked_pages scrubs the memory before free + OS::free_locked_pages(m_locked_pages); + } + } + +mlock_allocator& mlock_allocator::instance() + { + static mlock_allocator mlock; + return mlock; + } + +} diff --git a/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.h b/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.h new file mode 100644 index 0000000000..8d1d249809 --- /dev/null +++ b/comm/third_party/botan/src/lib/utils/locking_allocator/locking_allocator.h @@ -0,0 +1,45 @@ +/* +* Mlock Allocator +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MLOCK_ALLOCATOR_H_ +#define BOTAN_MLOCK_ALLOCATOR_H_ + +#include <botan/types.h> +#include <vector> +#include <memory> + +BOTAN_FUTURE_INTERNAL_HEADER(locking_allocator.h) + +namespace Botan { + +class Memory_Pool; + +class BOTAN_PUBLIC_API(2,0) mlock_allocator final + { + public: + static mlock_allocator& instance(); + + void* allocate(size_t num_elems, size_t elem_size); + + bool deallocate(void* p, size_t num_elems, size_t elem_size) noexcept; + + mlock_allocator(const mlock_allocator&) = delete; + + mlock_allocator& operator=(const mlock_allocator&) = delete; + + private: + mlock_allocator(); + + ~mlock_allocator(); + + std::unique_ptr<Memory_Pool> m_pool; + std::vector<void*> m_locked_pages; + }; + +} + +#endif |