Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

Public Member Functions | Static Public Member Functions | List of all members
Botan::mlock_allocator Class Reference

`#include <locking_allocator.h>`

## Public Member Functions
void * | allocate (size_t num_elems, size_t elem_size)
bool | deallocate (void *p, size_t num_elems, size_t elem_size)
| mlock_allocator (const mlock_allocator &)=delete
mlock_allocator & | operator= (const mlock_allocator &)=delete

## Static Public Member Functions
static mlock_allocator & | instance ()

## Detailed Description

Definition at line 17 of file locking_allocator.h.

## Constructor & Destructor Documentation

Botan::mlock_allocator::mlock_allocator | ( | const mlock_allocator & |  | ) |
| delete

## Member Function Documentation

void * Botan::mlock_allocator::allocate | ( | size_t | num_elems,
|  | size_t | elem_size
| ) |  |

Definition at line 45 of file locking_allocator.cpp.

References BOTAN_ASSERT, and Botan::clear_mem().

46 {
47 if(!m_pool)
48 return nullptr;
49
50 const size_t n = num_elems * elem_size;
51 const size_t alignment = 16;
52
53 if(n / elem_size != num_elems)
54 return nullptr; // overflow!
55
56 if(n > m_poolsize)
57 return nullptr;
58 if(n < BOTAN_MLOCK_ALLOCATOR_MIN_ALLOCATION || n > BOTAN_MLOCK_ALLOCATOR_MAX_ALLOCATION)
59 return nullptr;
60
61 lock_guard_type<mutex_type> lock(m_mutex);
62
63 auto best_fit = m_freelist.end();
64
65 for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i)
66 {
67 // If we have a perfect fit, use it immediately
68 if(i->second == n && (i->first % alignment) == 0)
69 {
70 const size_t offset = i->first;
71 m_freelist.erase(i);
72 clear_mem(m_pool + offset, n);
73
74 BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset) % alignment == 0,
75 "Returning correctly aligned pointer");
76
77 return m_pool + offset;
78 }
79
80 if((i->second >= (n + padding_for_alignment(i->first, alignment)) &&
81 ((best_fit == m_freelist.end()) || (best_fit->second > i->second))))
82 {
83 best_fit = i;
84 }
85 }
86
87 if(best_fit != m_freelist.end())
88 {
89 const size_t offset = best_fit->first;
90
91 const size_t alignment_padding = padding_for_alignment(offset, alignment);
92
93 best_fit->first += n + alignment_padding;
94 best_fit->second -= n + alignment_padding;
95
96 // Need to realign, split the block
97 if(alignment_padding)
98 {
99 /*
100 If we used the entire block except for small piece used for
101 alignment at the beginning, so just update the entry already
102 in place (as it is in the correct location), rather than
103 deleting the empty range and inserting the new one in the
104 same location.
105 */
106 if(best_fit->second == 0)
107 {
108 best_fit->first = offset;
109 best_fit->second = alignment_padding;
110 }
111 else
112 m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding));
113 }
114
115 clear_mem(m_pool + offset + alignment_padding, n);
116
117 BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset + alignment_padding) % alignment == 0,
118 "Returning correctly aligned pointer");
119
120 return m_pool + offset + alignment_padding;
121 }
122
123 return nullptr;
124 }
Botan::clear_mem
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27

bool Botan::mlock_allocator::deallocate | ( | void * | p,
|  | size_t | num_elems,
|  | size_t | elem_size
| ) |  |

Definition at line 126 of file locking_allocator.cpp.

References BOTAN_ASSERT.

127 {
128 if(!m_pool)
129 return false;
130
131 size_t n = num_elems * elem_size;
132
133 /*
134 We return nullptr in allocate if there was an overflow, so we
135 should never ever see an overflow in a deallocation.
136 */
137 BOTAN_ASSERT(n / elem_size == num_elems,
138 "No overflow in deallocation");
139
140 if(!ptr_in_pool(m_pool, m_poolsize, p, n))
141 return false;
142
143 std::memset(p, 0, n);
144
145 lock_guard_type<mutex_type> lock(m_mutex);
146
147 const size_t start = static_cast<uint8_t*>(p) - m_pool;
148
149 auto comp = [](std::pair<size_t, size_t> x, std::pair<size_t, size_t> y){ return x.first < y.first; };
150
151 auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(),
152 std::make_pair(start, 0), comp);
153
154 // try to merge with later block
155 if(i != m_freelist.end() && start + n == i->first)
156 {
157 i->first = start;
158 i->second += n;
159 n = 0;
160 }
161
162 // try to merge with previous block
163 if(i != m_freelist.begin())
164 {
165 auto prev = std::prev(i);
166
167 if(prev->first + prev->second == start)
168 {
169 if(n)
170 {
171 prev->second += n;
172 n = 0;
173 }
174 else
175 {
176 // merge adjoining
177 prev->second += i->second;
178 m_freelist.erase(i);
179 }
180 }
181 }
182
183 if(n != 0) // no merge possible?
184 m_freelist.insert(i, std::make_pair(start, n));
185
186 return true;
187 }
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27

mlock_allocator & Botan::mlock_allocator::instance | ( |  | ) |
| static

Definition at line 221 of file locking_allocator.cpp.

Referenced by Botan::secure_allocator< T >::allocate(), and Botan::secure_allocator< T >::deallocate().

222 {
223 static mlock_allocator mlock;
224 return mlock;
225 }
Botan::mlock_allocator::mlock_allocator
mlock_allocator(const mlock_allocator &)=delete

mlock_allocator& Botan::mlock_allocator::operator= | ( | const mlock_allocator & |  | ) |
| delete

The documentation for this class was generated from the following files:

- src/lib/utils/locking_allocator/locking_allocator.h
- src/lib/utils/locking_allocator/locking_allocator.cpp