Ensured that messages are aligned to 8 byte words on 64bit ARM 75/33375/1
authorDavid Steele <david.steele@partner.samsung.com>
Thu, 8 Jan 2015 17:58:28 +0000 (17:58 +0000)
committerDavid Steele <david.steele@partner.samsung.com>
Thu, 8 Jan 2015 17:58:28 +0000 (17:58 +0000)
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 <david.steele@partner.samsung.com>
dali/internal/common/message-buffer.cpp
dali/internal/common/message-buffer.h

index ae861b6..869bcfc 100644 (file)
@@ -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<unsigned int*>(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<unsigned int*>( realloc( mData, newCapacity * sizeof(unsigned int) ) );
+    WordType* oldData = mData;
+    mData = reinterpret_cast<WordType*>( 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<unsigned int*>( malloc( newCapacity * sizeof(unsigned int) ) );
+    mData = reinterpret_cast<WordType*>( 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)
 {
index 0025106..8e1a17a 100644 (file)
@@ -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