allocator alignment issues...

Discussion in 'C++' started by Chris Thomasson, Aug 22, 2007.

  1. I found some time to work a little more on my C++ allocator project. Here is
    some of the basic alignment code that I am thinking about using:

    ----------------
    #include <cstdio>
    #include <cstring>
    #include <cassert>


    // attempts to extract the alignemnt of a type T
    template<typename T>
    class align_of {
    struct temp {
    char m_offset;
    T m_object;
    };

    public:
    enum result_e {
    c_result = sizeof(temp) > sizeof(T) ?
    sizeof(temp) - sizeof(T) : sizeof(T)
    };
    };


    // attempts to extract an aligned buffer from _this
    template<typename T>
    static char* align_ptr(
    char const* const _this,
    ptrdiff_t alignsz = align_of<T>::c_result
    ) {
    ptrdiff_t offsetsz =
    reinterpret_cast<ptrdiff_t>(_this) % alignsz;

    if (offsetsz) {
    assert(offsetsz < alignsz);

    char const* const offsetptr =
    reinterpret_cast<char const*>(_this) + alignsz - offsetsz;

    if (reinterpret_cast<ptrdiff_t>(offsetptr) % alignsz) {
    assert(! (reinterpret_cast<ptrdiff_t>(offsetptr) % alignsz));
    throw;
    }

    printf("%p alignptr(%p, %i); // offset %i\n",
    (void*)offsetptr, (void*)_this, alignsz, offsetsz);

    return const_cast<char*>(offsetptr);
    }

    printf("%p alignptr(%p, %i);\n",
    (void*)_this, (void*)_this, alignsz);

    return const_cast<char*>(_this);
    }


    // a buffer and an aligned pointer into it...
    template<size_t T_sz, ptrdiff_t T_alignsz = T_sz>
    struct aligned_buf {
    enum const_e {
    c_alignsz = T_alignsz,
    c_alignobjsz = T_sz + c_alignsz - 1
    };

    char c_bufraw[c_alignobjsz];
    char* const c_bufalign;

    aligned_buf() :
    c_bufalign(align_ptr<char>(c_bufraw, c_alignsz)) {
    memset(c_bufraw, 0, c_alignobjsz);
    }

    char* load_align_ptr(ptrdiff_t alignsz) const {
    char* const ptr = align_ptr<char>(c_bufalign, alignsz);
    return ptr;
    }
    };


    /* App
    ____________________________________________________*/


    // platform specific
    namespace platform {
    namespace os {
    enum const_e {
    c_pagesz = 8192
    };
    }

    namespace arch {
    enum const_e {
    c_l2cachelinesz = 128
    };
    }
    }


    // misc types...
    struct temp1 {
    char m_1;
    short m_2;
    };

    struct temp2 {
    char m_1;
    temp1 m_2;
    float m_3;
    };

    struct temp3 {
    char m_1;
    temp2 m_2;
    double m_3;
    };


    // os page(s) w/ page-boundary alignment type
    template<size_t T_pages>
    struct pagebuf {
    typedef aligned_buf<
    platform::eek:s::c_pagesz * T_pages,
    platform::eek:s::c_pagesz> pagebuf_t;

    // pagebuf is os page aligned on page-boundary
    pagebuf_t m_buf;
    };


    int main(void) {
    {
    // create 4 pages on the stack.
    typedef pagebuf<4> pages_t;
    pages_t pages;

    // l2cachebuf is aligned off of pagebuf
    char* const l2cachebuf =
    pages.m_buf.load_align_ptr(platform::arch::c_l2cachelinesz);


    // display page alignment info
    printf("\n\n\
    (%u)-pages sizeof\n\
    (%p)-pages.m_buf.c_bufraw\n\
    (%p)-pages.m_buf.c_bufalign\n\
    (%p)-l2cachebuf\n",
    sizeof(pages),
    (void*)pages.m_buf.c_bufraw,
    (void*)pages.m_buf.c_bufalign,
    (void*)l2cachebuf);


    // display basic type alignment info
    printf("\n\n\
    (sz:%u\talign:%i)-char\n\
    (sz:%u\talign:%i)-short\n\
    (sz:%u\talign:%i)-long\n\
    (sz:%u\talign:%i)-float\n\
    (sz:%u\talign:%i)-double\n\
    (sz:%u\talign:%i)-long double\n\
    (sz:%u\talign:%i)-void* align\n\
    (sz:%u\talign:%i)-void* (*) (void*)\n\
    (sz:%u\talign:%i)-temp1\n\
    (sz:%u\talign:%i)-temp2\n\
    (sz:%u\talign:%i)-temp3\n",
    sizeof(char), align_of<char>::c_result,
    sizeof(short), align_of<short>::c_result,
    sizeof(long), align_of<long>::c_result,
    sizeof(float), align_of<float>::c_result,
    sizeof(double), align_of<double>::c_result,
    sizeof(long double), align_of<long double>::c_result,
    sizeof(void*), align_of<void*>::c_result,
    sizeof(void* (*) (void*)), align_of<void* (*) (void*)>::c_result,
    sizeof(temp1), align_of<temp1>::c_result,
    sizeof(temp2), align_of<temp2>::c_result,
    sizeof(temp3), align_of<temp3>::c_result);
    }

    puts("\n\n\n\
    _______________________\npress <enter> to exit...\n");
    return getchar();
    }

    ----------------


    This alignment code will be used in a per-thread C++ allocator scheme. I am
    always looking for better ways of doing the "alignment" stuff. If you have
    any suggestions I would like to hear them...
    Chris Thomasson, Aug 22, 2007
    #1
    1. Advertising

  2. "Chris Thomasson" <> wrote in message
    news:...
    >I found some time to work a little more on my C++ allocator project. Here
    >is some of the basic alignment code that I am thinking about using:
    >
    > ----------------
    > #include <cstdio>
    > #include <cstring>
    > #include <cassert>

    [...]

    OOPS!

    I forgot to add:

    #include <cstddef>


    darn. Sorry about that.
    Chris Thomasson, Aug 22, 2007
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Romeo Colacitti

    Custom memory allocator - alignment

    Romeo Colacitti, Mar 4, 2005, in forum: C Programming
    Replies:
    4
    Views:
    744
    Chris Torek
    Mar 7, 2005
  2. Lionel B
    Replies:
    10
    Views:
    923
    Lionel B
    Jan 2, 2007
  3. mathemagic
    Replies:
    5
    Views:
    1,140
    Alan Johnson
    Feb 11, 2007
  4. ranin02
    Replies:
    2
    Views:
    756
    ranin02
    Aug 27, 2007
  5. Spiros Bousbouras

    Re: standard memory allocator alignment issue...

    Spiros Bousbouras, May 13, 2008, in forum: C Programming
    Replies:
    9
    Views:
    302
    Spiros Bousbouras
    May 13, 2008
Loading...

Share This Page