diff options
-rw-r--r-- | src/alloc/locking_allocator/locking_allocator.cpp | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/alloc/locking_allocator/locking_allocator.cpp b/src/alloc/locking_allocator/locking_allocator.cpp index bb1b6abcf..2e9e44c44 100644 --- a/src/alloc/locking_allocator/locking_allocator.cpp +++ b/src/alloc/locking_allocator/locking_allocator.cpp @@ -54,6 +54,14 @@ bool ptr_in_pool(const void* pool_ptr, size_t poolsize, return true; } +size_t padding_for_alignment(size_t offset, size_t desired_alignment) + { + size_t mod = offset % desired_alignment; + if(mod == 0) + return 0; // already right on + return desired_alignment - mod; + } + } void* mlock_allocator::allocate(size_t n, size_t alignment) @@ -73,11 +81,15 @@ void* mlock_allocator::allocate(size_t n, size_t alignment) const size_t offset = i->first; m_freelist.erase(i); ::memset(m_pool + offset, 0, n); + + BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset) % alignment == 0, + "Returning correctly aligned pointer"); + return m_pool + offset; } - if((i->second > (i->first % alignment) + n) && - ((best_fit == m_freelist.end()) || (best_fit->second > i->second))) + if((i->second >= (n + padding_for_alignment(i->first, alignment)) && + ((best_fit == m_freelist.end()) || (best_fit->second > i->second)))) { best_fit = i; } @@ -87,17 +99,31 @@ void* mlock_allocator::allocate(size_t n, size_t alignment) { const size_t offset = best_fit->first; - size_t alignment_padding = offset % alignment; + const size_t alignment_padding = padding_for_alignment(offset, alignment); best_fit->first += n + alignment_padding; best_fit->second -= n + alignment_padding; // Need to realign, split the block if(alignment_padding) - m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding)); + { + if(best_fit->second == 0) + { + /* + We used the entire block except for small piece used for + alignment at the beginning, so just update this entry. + */ + best_fit->second = alignment_padding; + } + else + m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding)); + } ::memset(m_pool + offset + alignment_padding, 0, n); + BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset + alignment_padding) % alignment == 0, + "Returning correctly aligned pointer"); + return m_pool + offset + alignment_padding; } |