0024405: TKernel - add aligned allocator class Standard_MMgrAligned
authorkgv <kgv@opencascade.com>
Thu, 3 Apr 2014 12:31:35 +0000 (16:31 +0400)
committerapn <apn@opencascade.com>
Fri, 4 Apr 2014 08:57:30 +0000 (12:57 +0400)
New class NCollection_AlignedAllocator.
New macros STANDARD_ALIGNED.
New methods Standard::AllocateAligned() and Standard::FreeAligned().
Add missing Standard_EXPORT

src/Image/Image_PixMap.cxx
src/NCollection/FILES
src/NCollection/NCollection_AlignedAllocator.cxx [new file with mode: 0644]
src/NCollection/NCollection_AlignedAllocator.hxx [new file with mode: 0644]
src/Standard/Standard.cdl
src/Standard/Standard.cxx
src/Standard/Standard_DefineAlloc.hxx

index 7043cdd..1f45138 100644 (file)
 // commercial license or contractual agreement.
 
 #include <Image_PixMap.hxx>
-
-#ifdef _MSC_VER
-  #include <malloc.h>
-#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
-  #include <mm_malloc.h>
-#else
-  extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theBytesCount);
-#endif
-
-template<typename TypePtr>
-inline TypePtr MemAllocAligned (const Standard_Size& theBytesCount,
-                                const Standard_Size& theAlign = 16)
-{
-#if defined(_MSC_VER)
-  return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
-#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
-  return (TypePtr )     _mm_malloc (theBytesCount, theAlign);
-#else
-  void* aPtr;
-  if (posix_memalign (&aPtr, theAlign, theBytesCount))
-  {
-    aPtr = NULL;
-  }
-  return (TypePtr )aPtr;
-#endif
-}
-
-inline void MemFreeAligned (void* thePtrAligned)
-{
-#if defined(_MSC_VER)
-  _aligned_free (thePtrAligned);
-#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
-  _mm_free (thePtrAligned);
-#else
-  free (thePtrAligned);
-#endif
-}
+#include <Standard.hxx>
 
 IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
@@ -171,7 +135,7 @@ bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
     // use argument only if it greater
     myData.mySizeRowBytes = theSizeRowBytes;
   }
-  myData.myDataPtr = MemAllocAligned<Standard_Byte*> (SizeBytes());
+  myData.myDataPtr = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), 16);
   myIsOwnPointer   = true;
   setTopDown();
   return myData.myDataPtr != NULL;
@@ -222,7 +186,7 @@ void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
 {
   if (myIsOwnPointer && (myData.myDataPtr != NULL))
   {
-    MemFreeAligned (myData.myDataPtr);
+    Standard::FreeAligned (myData.myDataPtr);
   }
   myData.myDataPtr = myData.myTopRowPtr = NULL;
   myIsOwnPointer = true;
index ae79b55..dba4e4d 100755 (executable)
@@ -4,6 +4,8 @@ NCollection_BaseAllocator.hxx
 NCollection_BaseAllocator.cxx
 NCollection_IncAllocator.hxx
 NCollection_IncAllocator.cxx
+NCollection_AlignedAllocator.hxx
+NCollection_AlignedAllocator.cxx
 NCollection_HeapAllocator.hxx
 NCollection_HeapAllocator.cxx
 NCollection_StdAllocator.hxx
diff --git a/src/NCollection/NCollection_AlignedAllocator.cxx b/src/NCollection/NCollection_AlignedAllocator.cxx
new file mode 100644 (file)
index 0000000..5a9680e
--- /dev/null
@@ -0,0 +1,47 @@
+// Created on: 2014-03-31
+// Created by: Kirill Gavrilov
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <NCollection_AlignedAllocator.hxx>
+
+IMPLEMENT_STANDARD_HANDLE  (NCollection_AlignedAllocator, NCollection_BaseAllocator)
+IMPLEMENT_STANDARD_RTTIEXT (NCollection_AlignedAllocator, NCollection_BaseAllocator)
+
+//=======================================================================
+//function : NCollection_AlignedAllocator()
+//purpose  : Constructor
+//=======================================================================
+NCollection_AlignedAllocator::NCollection_AlignedAllocator (const size_t theAlignment)
+: myAlignment (theAlignment)
+{
+  //
+}
+
+//=======================================================================
+//function : Allocate
+//purpose  : allocate a memory
+//=======================================================================
+void* NCollection_AlignedAllocator::Allocate (const size_t theSize)
+{
+  return Standard::AllocateAligned (theSize, myAlignment);
+}
+
+//=======================================================================
+//function : Free
+//purpose  :
+//=======================================================================
+void NCollection_AlignedAllocator::Free (void* thePtr)
+{
+  Standard::FreeAligned (thePtr);
+}
diff --git a/src/NCollection/NCollection_AlignedAllocator.hxx b/src/NCollection/NCollection_AlignedAllocator.hxx
new file mode 100644 (file)
index 0000000..d3d6f56
--- /dev/null
@@ -0,0 +1,56 @@
+// Created on: 2014-03-31
+// Created by: Kirill Gavrilov
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef NCollection_AlignedAllocator_HeaderFile
+#define NCollection_AlignedAllocator_HeaderFile
+
+#include <NCollection_BaseAllocator.hxx>
+#include <Standard.hxx>
+
+//! NCollection allocator with managed memory alignment capabilities.
+class NCollection_AlignedAllocator : public NCollection_BaseAllocator
+{
+public:
+
+  //! Constructor. The alignment should be specified explicitly:
+  //! 16 bytes for SSE instructions
+  //! 32 bytes for AVX instructions
+  Standard_EXPORT NCollection_AlignedAllocator (const size_t theAlignment);
+
+  //! Allocate memory with given size. Returns NULL on failure.
+  Standard_EXPORT virtual void* Allocate (const size_t theSize);
+
+  //! Free a previously allocated memory.
+  Standard_EXPORT virtual void  Free (void* thePtr);
+
+private:
+
+  NCollection_AlignedAllocator            (const NCollection_AlignedAllocator& );
+  NCollection_AlignedAllocator& operator= (const NCollection_AlignedAllocator& );
+
+protected:
+
+  size_t myAlignment; //!< alignment in bytes
+
+public:
+
+  DEFINE_STANDARD_RTTI (NCollection_AlignedAllocator)
+
+};
+
+// Definition of HANDLE object using Standard_DefineHandle.hxx
+DEFINE_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator)
+
+#endif // NCollection_AlignedAllocator_HeaderFile
index 6be6cf6..311f32d 100644 (file)
@@ -145,7 +145,21 @@ is
     ---Purpose:  Reallocates memory blocks 
     --           aStorage - previously allocated memory block 
     --           aNewSize - new size in bytes 
-     
+
+    AllocateAligned (theSize  : Size from Standard;
+                     theAlign : Size from Standard)
+    returns Address from Standard;
+    ---Purpose:  Allocates aligned memory blocks.
+    -- Should be used with CPU instructions which require specific alignment.
+    -- For example: SSE requires 16 bytes, AVX requires 32 bytes.
+    -- @param theSize  bytes to allocate
+    -- @param theAlign alignment in bytes
+
+    FreeAligned (thePtrAligned : Address from Standard);
+    ---Purpose:  Deallocates memory blocks
+    -- @param thePtrAligned the memory block previously allocated with AllocateAligned()
+    ---C++: alias "template <typename T> static inline void FreeAligned (T*& thePtrAligned) { FreeAligned ((void* )thePtrAligned); thePtrAligned = 0; }"
+
     Purge returns Integer from Standard; 
     ---Purpose:  Deallocates the storage retained on the free list 
     --           and clears the list. 
index f809904..d33b312 100644 (file)
   #include <locale.h>
 #endif
 
+#ifdef _MSC_VER
+  #include <malloc.h>
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
+  #include <mm_malloc.h>
+#else
+  extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theSize);
+#endif
+
 #ifndef OCCT_MMGT_OPT_DEFAULT
 #define OCCT_MMGT_OPT_DEFAULT 0
 #endif
@@ -183,7 +191,7 @@ Standard_Address Standard::Allocate(const Standard_Size size)
 }
 
 //=======================================================================
-//function : FreeAddress
+//function : Free
 //purpose  : 
 //=======================================================================
 
@@ -212,3 +220,41 @@ Standard_Integer Standard::Purge()
 {
   return GetMMgr()->Purge();
 }
+
+//=======================================================================
+//function : AllocateAligned
+//purpose  :
+//=======================================================================
+
+Standard_Address Standard::AllocateAligned (const Standard_Size theSize,
+                                            const Standard_Size theAlign)
+{
+#if defined(_MSC_VER)
+  return _aligned_malloc (theSize, theAlign);
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
+  return      _mm_malloc (theSize, theAlign);
+#else
+  void* aPtr;
+  if (posix_memalign (&aPtr, theAlign, theSize))
+  {
+    return NULL;
+  }
+  return aPtr;
+#endif
+}
+
+//=======================================================================
+//function : FreeAligned
+//purpose  :
+//=======================================================================
+
+void Standard::FreeAligned (Standard_Address thePtrAligned)
+{
+#if defined(_MSC_VER)
+  _aligned_free (thePtrAligned);
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
+  _mm_free (thePtrAligned);
+#else
+  free (thePtrAligned);
+#endif
+}
index 20c16b0..d2bb461 100644 (file)
@@ -14,7 +14,7 @@
 // commercial license or contractual agreement.
 
 #ifndef _Standard_DefineAlloc_HeaderFile
-# define _Standard_DefineAlloc_HeaderFile
+#define _Standard_DefineAlloc_HeaderFile
 
 // Macro to override new and delete operators for arrays.
 // Defined to empty for old SUN compiler
@@ -76,4 +76,17 @@ inline void* operator new(size_t,void* anAddress)
 #endif
 #endif
 
+//! @def STANDARD_ALIGNED(theAlignment, theType, theVar)
+//! Declare variable with memory alignment.
+//! @code
+//!   static const STANDARD_ALIGNED(8, char, THE_ARRAY)[] = {0xFF, 0xFE, 0xFA, 0xFB, 0xFF, 0x11, 0x22, 0x33};
+//! @endcode
+#if defined(_MSC_VER)
+  #define STANDARD_ALIGNED(theAlignment, theType, theVar) __declspec(align(theAlignment)) theType theVar
+#elif defined(__GNUC__)
+  #define STANDARD_ALIGNED(theAlignment, theType, theVar) theType __attribute__ ((aligned (theAlignment))) theVar
+#else
+  #define STANDARD_ALIGNED(theAlignment, theType, theVar) theType theVar
 #endif
+
+#endif // _Standard_DefineAlloc_HeaderFile