From d4b9365473718d89ddb7905351613bb51ad2d9b9 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 8 Jan 2015 17:58:28 +0000 Subject: [PATCH] Ensured that messages are aligned to 8 byte words on 64bit ARM Message buffers were aligning to sizeof(unsigned int), which is not the size of a word on 64bit arm. Instead, it should use sizeof(std::ptrdiff_t) to get word aligned memory. Change-Id: Id84818efcaccdf531792b6f22d9ad65fd67d1106 Signed-off-by: David Steele --- dali/internal/common/message-buffer.cpp | 23 +++++++++++++---------- dali/internal/common/message-buffer.h | 21 +++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/dali/internal/common/message-buffer.cpp b/dali/internal/common/message-buffer.cpp index ae861b6..869bcfc 100644 --- a/dali/internal/common/message-buffer.cpp +++ b/dali/internal/common/message-buffer.cpp @@ -37,7 +37,8 @@ const unsigned int MESSAGE_END_FIELD = 1u; // Size required to mark the end of const unsigned int MESSAGE_SIZE_PLUS_END_FIELD = MESSAGE_SIZE_FIELD + MESSAGE_END_FIELD; -const unsigned int MAX_DIVISION_BY_WORD_REMAINDER = sizeof(unsigned int) - 1u; // For word alignment on ARM +const unsigned int MAX_DIVISION_BY_WORD_REMAINDER = sizeof(Dali::Internal::MessageBuffer::WordType) - 1u; // For word alignment on ARM +const unsigned int WORD_SIZE = sizeof(Dali::Internal::MessageBuffer::WordType); } // unnamed namespace @@ -48,7 +49,7 @@ namespace Internal { MessageBuffer::MessageBuffer( std::size_t initialCapacity ) -: mInitialCapacity( initialCapacity / sizeof(unsigned int) ), +: mInitialCapacity( initialCapacity / WORD_SIZE ), mData( NULL ), mNextSlot( NULL ), mCapacity( 0 ), @@ -65,7 +66,8 @@ unsigned int* MessageBuffer::ReserveMessageSlot( std::size_t size ) { DALI_ASSERT_DEBUG( 0 != size ); - std::size_t requestedSize = (size + MAX_DIVISION_BY_WORD_REMAINDER) / sizeof(unsigned int); + // Number of aligned words required to handle a message of size in bytes + std::size_t requestedSize = (size + MAX_DIVISION_BY_WORD_REMAINDER) / WORD_SIZE; std::size_t requiredSize = requestedSize + MESSAGE_SIZE_PLUS_END_FIELD; // Keep doubling the additional capacity until we have enough @@ -85,7 +87,7 @@ unsigned int* MessageBuffer::ReserveMessageSlot( std::size_t size ) } // Now reserve the slot - unsigned int* slot = mNextSlot; + WordType* slot = mNextSlot; *slot++ = requestedSize; // Object size marker is stored in first word @@ -95,12 +97,13 @@ unsigned int* MessageBuffer::ReserveMessageSlot( std::size_t size ) // End marker *mNextSlot = 0; - return slot; + // @todo Remove cast & change all messages to use WordType instead + return reinterpret_cast(slot); } std::size_t MessageBuffer::GetCapacity() const { - return mCapacity * sizeof(unsigned int); + return mCapacity * WORD_SIZE; } MessageBuffer::Iterator MessageBuffer::Begin() const @@ -128,8 +131,8 @@ void MessageBuffer::IncreaseCapacity( std::size_t newCapacity ) { // Often this avoids the need to copy memory - unsigned int* oldData = mData; - mData = reinterpret_cast( realloc( mData, newCapacity * sizeof(unsigned int) ) ); + WordType* oldData = mData; + mData = reinterpret_cast( realloc( mData, newCapacity * WORD_SIZE ) ); // if realloc fails the old data is still valid if( !mData ) @@ -141,7 +144,7 @@ void MessageBuffer::IncreaseCapacity( std::size_t newCapacity ) } else { - mData = reinterpret_cast( malloc( newCapacity * sizeof(unsigned int) ) ); + mData = reinterpret_cast( malloc( newCapacity * WORD_SIZE ) ); } DALI_ASSERT_ALWAYS( NULL != mData ); @@ -149,7 +152,7 @@ void MessageBuffer::IncreaseCapacity( std::size_t newCapacity ) mNextSlot = mData + mSize; } -MessageBuffer::Iterator::Iterator(unsigned int* current) +MessageBuffer::Iterator::Iterator(WordType* current) : mCurrent(current), mMessageSize(0) { diff --git a/dali/internal/common/message-buffer.h b/dali/internal/common/message-buffer.h index 0025106..8e1a17a 100644 --- a/dali/internal/common/message-buffer.h +++ b/dali/internal/common/message-buffer.h @@ -33,6 +33,7 @@ namespace Internal class MessageBuffer { public: + typedef std::ptrdiff_t WordType; /** * Create a new MessageBuffer @@ -49,8 +50,8 @@ public: /** * Reserve space for another message in the buffer. * @pre size is greater than zero. - * @param[in] The message size with respect to the size of type "char". - * @return A pointer to the address allocated for the message. + * @param[in] size The message size with respect to the size of type "char". + * @return A pointer to the address allocated for the message, aligned to a word boundary */ unsigned int* ReserveMessageSlot( std::size_t size ); @@ -68,7 +69,7 @@ public: public: // Constructor - Iterator(unsigned int* current); + Iterator(WordType* current); // Inlined for performance bool IsValid() @@ -78,7 +79,7 @@ public: } // Inlined for performance - unsigned int* Get() + WordType* Get() { return ( 0 != mMessageSize ) ? mCurrent : NULL; } @@ -101,8 +102,8 @@ public: private: - unsigned int* mCurrent; - unsigned int mMessageSize; + WordType* mCurrent; + std::size_t mMessageSize; }; /** @@ -137,11 +138,11 @@ private: std::size_t mInitialCapacity; ///< The capacity to allocate during first call to ReserveMessageSlot - unsigned int* mData; ///< The data allocated for the message buffer - unsigned int* mNextSlot; ///< The next free location in the buffer + WordType* mData; ///< The data allocated for the message buffer + WordType* mNextSlot; ///< The next free location in the buffer - std::size_t mCapacity; ///< The memory allocated with respect to sizeof(unsigned int) - std::size_t mSize; ///< The memory reserved for messages with respect to sizeof(unsigned int) + std::size_t mCapacity; ///< The memory allocated with respect to sizeof(WordType) + std::size_t mSize; ///< The memory reserved for messages with respect to sizeof(WordType) }; } // namespace Internal -- 2.7.4