libcruft-util/test/alloc/aligned/foreign.cpp
Danny Robson c2265b9ed2 alloc: add aligned::foreign allocator
sometimes we need to ensure memory allocation has a particular alignment
in an _offset_ buffer (which we have no control over, eg renderdoc's
OpenGL buffers).

this applies an offset to various operations that make the
aligned::direct allocator correctly align allocations for buffers that
aren't themselves aligned.
2018-03-02 12:21:38 +11:00

55 lines
1.6 KiB
C++

#include "alloc/raw/aligned/foreign.hpp"
#include "alloc/raw/linear.hpp"
#include "pointer.hpp"
#include "tap.hpp"
int
main ()
{
static std::byte buffer[1024*1024];
static constexpr std::size_t alignment = 3;
static constexpr std::size_t increment = 1;
// ensure we have an base pointer that's off-by-one to a likely natural
// system alignment
std::byte* base = util::align (
std::data (buffer),
alignof (std::max_align_t)
) + increment;
util::alloc::raw::aligned::foreign<util::alloc::raw::linear> alloc (
util::view(base,std::end(buffer)),
alignment
);
util::TAP::logger tap;
// ensure the first element allocated falls at the base address
tap.expect_eq (base, alloc.data (), "allocator base address is the supplied base address");
tap.expect_eq (base, alloc.allocate (8), "first allocation is the supplied base address");
// allocate a range of values and make sure they all satisfy our alignment.
// don't choose values which are likely to combine with the testing
// alignment to produce a likely system alignment. eg, 3 + 5 == 8 which is
// a power-of-2.
static const struct {
size_t size;
const char *message;
} TESTS[] = {
{ 9, "just over a power of two" },
{ 1, "a single byte" },
{ 64, "a cache line" },
{ 250, "multiple cache lines, but not a power of two" },
};
for (const auto &t: TESTS) {
auto ptr = (uintptr_t)alloc.allocate (t.size);
auto offset = ptr - (uintptr_t)base;
tap.expect_mod (offset, alignment, "%s", t.message);
}
return tap.status ();
};