1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
/**********************************************************************
Audacity: A Digital Audio Editor
MemoryX.cpp
Paul Licameli
**********************************************************************/
#include <cstdint>
#include "MemoryX.h"
// Make the symbol table non-empty
UTILITY_API void lib_utility_dummy_symbol()
{}
constexpr auto sizeof_align_val = sizeof(std::align_val_t);
void *NonInterferingBase::operator new(std::size_t count, std::align_val_t al)
{
using namespace std;
// Get an allocation with sufficient extra space to remember the alignment
// (And to do that, adjust the alignment to be not less than the alignment of
// an alignment value!).
// Also increase the allocation by one entire alignment.
al = max( al, static_cast<align_val_t>( alignof(align_val_t) ) );
const auto al_as_size = static_cast<size_t>(al);
auto ptr = static_cast<char*>(
::operator new( count + sizeof_align_val + al_as_size ) );
// Adjust the pointer to a properly aligned one, with a space just before it
// to remember the adjustment
ptr += sizeof_align_val;
auto integer = reinterpret_cast<uintptr_t>(ptr);
const auto partial = integer % al_as_size;
auto adjustment = partial ? al_as_size - partial : 0;
integer += adjustment;
ptr = reinterpret_cast<char*>(integer);
// Remember the adjustment
*(reinterpret_cast<size_t*>(ptr) - 1) = adjustment;
return ptr;
}
void NonInterferingBase::operator delete(void *ptr, std::align_val_t al)
{
// Find the adjustment
auto adjustment = *(reinterpret_cast<size_t*>(ptr) - 1);
// Apply the adjustment
auto p = reinterpret_cast<char*>(ptr) - adjustment - sizeof_align_val;
// Call through to default operator
::operator delete(p);
}
|