Allocation schema w.r.t. padding and alignment...

Discussion in 'C++' started by SenderX, May 13, 2004.

  1. SenderX

    SenderX Guest

    I am thinking of porting a library from C to C++, and was tinkering with
    ways to ensure proper struct padding and alignment. The library is very
    hardware specific, and will simply crash and/or perform bad if the memory
    some of its algos use is not properly padded and aligned. So I had to come
    up with a way to create several objects of the same class that have
    different alignment and padding...

    Consider my temporary solution, using placement new and templates:


    Example.cpp
    ( compiles with GCC and MSVC++6.0 )
    -----------------

    // C++ code created by C programmer!

    #include <iostream>
    #include <cassert>
    #include <cstddef>
    #include <new>


    #define AC_CACHE_LINE 128
    #define AC_ALGO1_ALIGN ( AC_CACHE_LINE / 2 )
    #define AC_ALGO2_ALIGN ( AC_CACHE_LINE * 2 )


    template< size_t T_Align >
    struct TExampleImpl_Padded
    {
    // snip

    int m_iExampleState;

    // Is this legal!?! Works for GCC... humm
    char PAD1[T_Align - sizeof( int )];
    };


    struct SExampleImpl
    {
    int m_iExampleState;
    };


    template< typename T_Impl, size_t T_Align /* snip */ >
    class TExample
    {

    public:

    TExample() : m_pImpl( 0 ), m_pImplMem( 0 )
    {
    // Assert
    if ( ! T_Align ||
    T_Align != 1 && ( ((ptrdiff_t)m_pImpl) % sizeof( size_t ) ) )
    {
    throw;
    }

    // Alloc and align
    m_pImplMem = ::eek:perator new( sizeof( T_Impl ) + ( T_Align - 1 ) );

    m_pImpl = new ( (void*)(( (((ptrdiff_t)m_pImplMem) + (T_Align - 1))
    & -(T_Align) )) ) T_Impl;

    // Assert
    if ( T_Align != 1 && ( ((ptrdiff_t)m_pImpl) % T_Align ) )
    {
    m_pImpl->~T_Impl();
    ::eek:perator delete( m_pImplMem );

    throw;
    }

    std::cout << m_pImpl << "::sizeof - " << sizeof( *m_pImpl ) <<
    std::endl;

    // Init impl
    m_pImpl->m_iExampleState = 0;
    }

    ~TExample()
    {
    assert( m_pImpl && m_pImplMem );

    // Dtor, placement new...
    m_pImpl->~T_Impl();
    ::eek:perator delete( m_pImplMem );
    }


    public:


    // snip


    private:

    T_Impl *m_pImpl;
    void *m_pImplMem;
    };


    // Now I can create a number of different padding and alignments

    typedef TExample< TExampleImpl_Padded< AC_CACHE_LINE >, AC_CACHE_LINE >
    CExample;
    typedef TExample< TExampleImpl_Padded< AC_ALGO1_ALIGN >, AC_ALGO1_ALIGN >
    CExampleAlgo1;
    typedef TExample< TExampleImpl_Padded< AC_ALGO2_ALIGN >, AC_ALGO2_ALIGN >
    CExampleAlgo2;
    typedef TExample< SExampleImpl, 1 > CLwExample;




    int main()
    {
    CExample s;
    CExampleAlgo1 sa1;
    CExampleAlgo2 sa2;
    CLwExample lws;

    return 0;
    }


    As you can see, this provides the solution I want, and passes all of the
    library's tests, but...

    Is this a non-portable crappy solution? If so, got anything better? I'm not
    that good at C++, I'm a C guy...

    ;)

    Thank you.
     
    SenderX, May 13, 2004
    #1
    1. Advertising

  2. SenderX

    SenderX Guest

    > public:
    >
    > TExample() : m_pImpl( 0 ), m_pImplMem( 0 )
    > {




    DOH!

    ***************
    > // Assert
    > if ( ! T_Align ||
    > T_Align != 1 && ( ((ptrdiff_t)m_pImpl) % sizeof( size_t ) ) )
    > {
    > throw;
    > }

    **************

    This was not suppose to be pasted in the example!

    Sorry.

    :O



    >
    > // Alloc and align
    > m_pImplMem = ::eek:perator new( sizeof( T_Impl ) + ( T_Align - 1 ) );
    >
    > m_pImpl = new ( (void*)(( (((ptrdiff_t)m_pImplMem) + (T_Align -

    1))
    > & -(T_Align) )) ) T_Impl;
     
    SenderX, May 13, 2004
    #2
    1. Advertising

  3. SenderX

    perry Guest

    you know, i use to be such a fan of c++

    i think it's the templates that get me down the most...

    and to think they've actually brought these over to Java now...

    - perry

    SenderX wrote:
    > I am thinking of porting a library from C to C++, and was tinkering with
    > ways to ensure proper struct padding and alignment. The library is very
    > hardware specific, and will simply crash and/or perform bad if the memory
    > some of its algos use is not properly padded and aligned. So I had to come
    > up with a way to create several objects of the same class that have
    > different alignment and padding...
    >
    > Consider my temporary solution, using placement new and templates:
    >
    >
    > Example.cpp
    > ( compiles with GCC and MSVC++6.0 )
    > -----------------
    >
    > // C++ code created by C programmer!
    >
    > #include <iostream>
    > #include <cassert>
    > #include <cstddef>
    > #include <new>
    >
    >
    > #define AC_CACHE_LINE 128
    > #define AC_ALGO1_ALIGN ( AC_CACHE_LINE / 2 )
    > #define AC_ALGO2_ALIGN ( AC_CACHE_LINE * 2 )
    >
    >
    > template< size_t T_Align >
    > struct TExampleImpl_Padded
    > {
    > // snip
    >
    > int m_iExampleState;
    >
    > // Is this legal!?! Works for GCC... humm
    > char PAD1[T_Align - sizeof( int )];
    > };
    >
    >
    > struct SExampleImpl
    > {
    > int m_iExampleState;
    > };
    >
    >
    > template< typename T_Impl, size_t T_Align /* snip */ >
    > class TExample
    > {
    >
    > public:
    >
    > TExample() : m_pImpl( 0 ), m_pImplMem( 0 )
    > {
    > // Assert
    > if ( ! T_Align ||
    > T_Align != 1 && ( ((ptrdiff_t)m_pImpl) % sizeof( size_t ) ) )
    > {
    > throw;
    > }
    >
    > // Alloc and align
    > m_pImplMem = ::eek:perator new( sizeof( T_Impl ) + ( T_Align - 1 ) );
    >
    > m_pImpl = new ( (void*)(( (((ptrdiff_t)m_pImplMem) + (T_Align - 1))
    > & -(T_Align) )) ) T_Impl;
    >
    > // Assert
    > if ( T_Align != 1 && ( ((ptrdiff_t)m_pImpl) % T_Align ) )
    > {
    > m_pImpl->~T_Impl();
    > ::eek:perator delete( m_pImplMem );
    >
    > throw;
    > }
    >
    > std::cout << m_pImpl << "::sizeof - " << sizeof( *m_pImpl ) <<
    > std::endl;
    >
    > // Init impl
    > m_pImpl->m_iExampleState = 0;
    > }
    >
    > ~TExample()
    > {
    > assert( m_pImpl && m_pImplMem );
    >
    > // Dtor, placement new...
    > m_pImpl->~T_Impl();
    > ::eek:perator delete( m_pImplMem );
    > }
    >
    >
    > public:
    >
    >
    > // snip
    >
    >
    > private:
    >
    > T_Impl *m_pImpl;
    > void *m_pImplMem;
    > };
    >
    >
    > // Now I can create a number of different padding and alignments
    >
    > typedef TExample< TExampleImpl_Padded< AC_CACHE_LINE >, AC_CACHE_LINE >
    > CExample;
    > typedef TExample< TExampleImpl_Padded< AC_ALGO1_ALIGN >, AC_ALGO1_ALIGN >
    > CExampleAlgo1;
    > typedef TExample< TExampleImpl_Padded< AC_ALGO2_ALIGN >, AC_ALGO2_ALIGN >
    > CExampleAlgo2;
    > typedef TExample< SExampleImpl, 1 > CLwExample;
    >
    >
    >
    >
    > int main()
    > {
    > CExample s;
    > CExampleAlgo1 sa1;
    > CExampleAlgo2 sa2;
    > CLwExample lws;
    >
    > return 0;
    > }
    >
    >
    > As you can see, this provides the solution I want, and passes all of the
    > library's tests, but...
    >
    > Is this a non-portable crappy solution? If so, got anything better? I'm not
    > that good at C++, I'm a C guy...
    >
    > ;)
    >
    > Thank you.
    >
    >
     
    perry, May 13, 2004
    #3
    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. Markus
    Replies:
    1
    Views:
    1,550
    Markus
    Nov 23, 2005
  2. Stanimir Stamenkov
    Replies:
    3
    Views:
    1,268
    Stanimir Stamenkov
    Apr 25, 2005
  3. Paul_Huang

    Memory Padding and alignment

    Paul_Huang, Sep 21, 2004, in forum: C++
    Replies:
    2
    Views:
    3,980
    Serge Paccalin
    Sep 21, 2004
  4. Spoon

    Padding and alignment

    Spoon, Feb 12, 2007, in forum: C++
    Replies:
    12
    Views:
    608
    Rolf Magnus
    Feb 13, 2007
  5. Andrew Tomazos
    Replies:
    7
    Views:
    863
    Richard Herring
    Jun 24, 2009
Loading...

Share This Page