align pointer in pool

have stack-based pool with allocation from end to begin (it's easier at least in assembler properly align memory).
Have pointer (that responds for current element) and align size (all time it's return value of alignof operator).
Read from Agner Fog example for real stack:
 
and esp, 0FFFFFFF0H ; (= -16) Align ESP by 16 

Want to do smth like
 
curr&=-(long)(align);


How to do same in c++ with properly type-checking? In particular what type of pointer should be?
Last edited on
have stack-based pool with allocation ...
What's wrong with alloca()?
How to do same in c++ with properly type-checking?
Check out http://en.cppreference.com/w/cpp/memory/align

what type of pointer should be
http://en.cppreference.com/w/cpp/types/aligned_storage or use alignas directly. Not a lot of compilers support it yet (many compilers offer alignas as a compiler-specific attribute, though, something like __attribute__((aligned(n))) )
Last edited on

What's wrong with alloca()?

Stack-based in sense of technology-based not in sense of usage of real stack.


http://en.cppreference.com/w/cpp/types/aligned_storage or use alignas directly. Not a lot of compilers support it yet (many compilers offer alignas as a compiler-specific attribute, though, something like __attribute__((aligned(n))) )

No, i need to do that for pool of different objects. I shouldn't only apply align in declaration/definition of object/variable but also apply to current pointer, which refers to current accesabe memory in pool. Since objects are different i must apply alignement each time i request memory.
E.g.
0) Have pool of 64 bytes aligned to 64. Pointer curr points to end.
1) Request one char (1 bytes with alignment=1) => after that curr points to end-1.
2) Request one int (4 bytes with alignment=4)=> curr points to end-8 i.e.
[end-8, end-5] goes for int and [end-4, end-2] just padded.

So, which type of pointer should be to safely apply that "logical and"?
Last edited on
so you're placing your items at their natural alignment? That doesn't even require any special attributes, except to get the initial 64-byte buffer aligned at 64.

If you were allocating at start, you'd just use std::align, something like this:

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
#include <iostream>
#include <memory>
int main()
{
    std::aligned_storage<64, 64>::type buf;

    void* p = reinterpret_cast<char*>(&buf);
    size_t space = sizeof buf;
    std::cout << "start = " << p << '\n';

    // allocate a char
    std::align(alignof(char), 1, p, space);
    std::cout << "after adjusting for a char\n"
              << "p = " << (void*)p << " spoace left " << space << '\n';
    // return (char*)p to the user so that they can write to this location
    // (e.g.. if you're writing an actual reusable allocator), but not until you 
    // advance your internal copy:
    p = (char*)p + sizeof(char);

    // allocate a int
    std::align(alignof(int), 1, p, space);
    std::cout << "after adjusting for an int\n"
              << "p = " << (void*)p << " space left " << space << '\n';
    // return (int*)p to the user so that they can write to this location
    p = (char*)p + sizeof(int);
}

start = 0x2ff21a00
after adjusting for a char
p = 0x2ff21a00 spoace left 64
after adjusting for an int
p = 0x2ff21a04 space left 61


going from the end is a bit awkward, I think the cleanest solution is to write your own pointer-adjusting function, similar to std::align.

You can take the source code of an std::align implementation from clang: http://llvm.org/svn/llvm-project/libcxx/trunk/src/memory.cpp
Last edited on

going from the end is a bit awkward

I thought it's more natural taking into account that real stack organized in that way.
Anyway thank you so much.
Actually you can see they did it via "and" too but with one addition overhead.
 
char* p2 = (char*)((size_t)(p1 + (alignment - 1)) & -alignment);

And yes, my problem just was properly proceed all those type conversions.
Topic archived. No new replies allowed.