locking_allocator.hpp
Go to the documentation of this file.
1 #ifndef CRYPTO3_MLOCK_ALLOCATOR_HPP
2 #define CRYPTO3_MLOCK_ALLOCATOR_HPP
3 
4 #include <nil/crypto3/utilities/detail/mem_pool/mem_pool.hpp>
5 #include <nil/crypto3/utilities/detail/os_utils.hpp>
6 
7 #include <vector>
8 #include <memory>
9 
10 namespace nil {
11  namespace crypto3 {
12 
13  class memory_pool;
14 
15  class mlock_allocator final {
16  public:
18  static mlock_allocator mlock;
19  return mlock;
20  }
21 
22  void *allocate(size_t num_elems, size_t elem_size) {
23  if (!m_pool) {
24  return nullptr;
25  }
26 
27  const size_t n = num_elems * elem_size;
28  if (n / elem_size != num_elems) {
29  return nullptr;
30  } // overflow!
31 
32  return m_pool->allocate(n);
33  }
34 
35  bool deallocate(void *p, size_t num_elems, size_t elem_size) BOOST_NOEXCEPT {
36  if (!m_pool) {
37  return false;
38  }
39 
40  size_t n = num_elems * elem_size;
41 
42  /*
43  We return nullptr in allocate if there was an overflow, so if an
44  overflow occurs here we know the pointer was not allocated by this pool.
45  */
46  if (n / elem_size != num_elems) {
47  return false;
48  }
49 
50  return m_pool->deallocate(p, n);
51  }
52 
53  mlock_allocator(const mlock_allocator &) = delete;
54 
56 
57  private:
58  mlock_allocator() {
59  const size_t mem_to_lock = get_memory_locking_limit();
60 
61  if (mem_to_lock) {
62  m_locked_pages = static_cast<uint8_t *>(allocate_locked_pages(mem_to_lock));
63 
64  if (m_locked_pages) {
65  m_locked_pages_size = mem_to_lock;
66  m_pool = std::make_unique<memory_pool>(m_locked_pages, m_locked_pages_size, system_page_size(),
67  CRYPTO3_MLOCK_ALLOCATOR_MIN_ALLOCATION,
68  CRYPTO3_MLOCK_ALLOCATOR_MAX_ALLOCATION, 4);
69  }
70  }
71  }
72 
73  ~mlock_allocator() {
74  if (m_pool) {
75  m_pool.reset();
76  // free_locked_pages scrubs the memory before free
77  free_locked_pages(m_locked_pages, m_locked_pages_size);
78  }
79  }
80 
81  std::unique_ptr<memory_pool> m_pool;
82  uint8_t *m_locked_pages = nullptr;
83  size_t m_locked_pages_size = 0;
84  };
85  } // namespace crypto3
86 } // namespace nil
87 
88 #endif
Definition: locking_allocator.hpp:15
bool deallocate(void *p, size_t num_elems, size_t elem_size) BOOST_NOEXCEPT
Definition: locking_allocator.hpp:35
mlock_allocator(const mlock_allocator &)=delete
void * allocate(size_t num_elems, size_t elem_size)
Definition: locking_allocator.hpp:22
static mlock_allocator & instance()
Definition: locking_allocator.hpp:17
mlock_allocator & operator=(const mlock_allocator &)=delete
Definition: pair.hpp:31