Line data Source code
1 : // Copyright (c) 2018-2021 The Dash Core developers 2 : // Copyright (c) 2021 The PIVX Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef PIVX_SUPPORT_ALLOCATORS_POOLED_SECURE_H 7 : #define PIVX_SUPPORT_ALLOCATORS_POOLED_SECURE_H 8 : 9 : #include "support/lockedpool.h" 10 : #include "support/cleanse.h" 11 : 12 : #include <string> 13 : #include <vector> 14 : 15 : #include <boost/pool/pool_alloc.hpp> 16 : 17 : // 18 : // Allocator that allocates memory in chunks from a pool, which in turn allocates larger chunks from secure memory 19 : // Memory is cleaned when freed as well. This allocator is NOT thread safe 20 : // 21 : template <typename T> 22 : struct pooled_secure_allocator : public std::allocator<T> { 23 : // MSVC8 default copy constructor is broken 24 : typedef std::allocator<T> base; 25 : typedef typename base::size_type size_type; 26 : typedef typename base::difference_type difference_type; 27 : typedef typename base::pointer pointer; 28 : typedef typename base::const_pointer const_pointer; 29 : typedef typename base::reference reference; 30 : typedef typename base::const_reference const_reference; 31 : typedef typename base::value_type value_type; 32 616 : explicit pooled_secure_allocator(const size_type nrequested_size = 32, 33 : const size_type nnext_size = 32, 34 : const size_type nmax_size = 0) throw() : 35 616 : pool(nrequested_size, nnext_size, nmax_size){} 36 616 : ~pooled_secure_allocator() throw() {} 37 : 38 373587 : T* allocate(std::size_t n, const void* hint = 0) 39 : { 40 373587 : size_t chunks = (n * sizeof(T) + pool.get_requested_size() - 1) / pool.get_requested_size(); 41 373587 : return static_cast<T*>(pool.ordered_malloc(chunks)); 42 : } 43 : 44 373587 : void deallocate(T* p, std::size_t n) 45 : { 46 373587 : if (!p) { 47 : return; 48 : } 49 : 50 373587 : size_t chunks = (n * sizeof(T) + pool.get_requested_size() - 1) / pool.get_requested_size(); 51 373587 : memory_cleanse(p, chunks * pool.get_requested_size()); 52 373587 : pool.ordered_free(p, chunks); 53 : } 54 : 55 : public: 56 : struct internal_secure_allocator { 57 : typedef std::size_t size_type; 58 : typedef std::ptrdiff_t difference_type; 59 : 60 286 : static char* malloc(const size_type bytes) 61 : { 62 286 : return static_cast<char*>(LockedPoolManager::Instance().alloc(bytes)); 63 : } 64 : 65 286 : static void free(char* const block) 66 : { 67 286 : LockedPoolManager::Instance().free(block); 68 286 : } 69 : }; 70 : private: 71 : boost::pool<internal_secure_allocator> pool; 72 : }; 73 : 74 : #endif // PIVX_SUPPORT_ALLOCATORS_POOLED_SECURE_H