0030329: Move BRepMesh_IncAllocator to NCollection package
authorkgv <kgv@opencascade.com>
Mon, 4 Feb 2019 09:21:14 +0000 (12:21 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 4 Feb 2019 14:48:14 +0000 (17:48 +0300)
NCollection_IncAllocator has been extended with optional mutex allocation (disabled by default).

src/BRepMesh/BRepMesh_FaceChecker.cxx
src/BRepMesh/BRepMesh_IncAllocator.hxx [deleted file]
src/BRepMesh/FILES
src/BRepMeshData/BRepMeshData_Model.cxx
src/NCollection/NCollection_IncAllocator.cxx
src/NCollection/NCollection_IncAllocator.hxx

index 8897c90..080e555 100644 (file)
@@ -18,7 +18,6 @@
 #include <IMeshData_Edge.hxx>
 #include <OSD_Parallel.hxx>
 #include <BRepMesh_GeomTool.hxx>
-#include <BRepMesh_IncAllocator.hxx>
 
 namespace
 {
diff --git a/src/BRepMesh/BRepMesh_IncAllocator.hxx b/src/BRepMesh/BRepMesh_IncAllocator.hxx
deleted file mode 100644 (file)
index 923acc0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Created on: 2016-06-20
-// Created by: Oleg AGASHIN
-// Copyright (c) 2016 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 _BRepMesh_IncAllocator_HeaderFile
-#define _BRepMesh_IncAllocator_HeaderFile
-
-#include <NCollection_IncAllocator.hxx>
-#include <Standard_Mutex.hxx>
-
-//! Extension for NCollection_IncAllocator implementing simple thread safety
-//! by introduction of Mutex. Intended for use in couple with BRepMeshData
-//! entities in order to prevent data races while building data model in
-//! parallel mode. Note that this allocator is supposed for use by collections
-//! which allocate memory by huge blocks at arbitrary moment, thus it should
-//! not introduce significant performance slow down.
-class BRepMesh_IncAllocator : public NCollection_IncAllocator
-{
-public:
-  //! Constructor
-  BRepMesh_IncAllocator(const size_t theBlockSize = DefaultBlockSize)
-    : NCollection_IncAllocator(theBlockSize)
-  {
-  }
-
-  //! Allocate memory with given size. Returns NULL on failure
-  virtual void* Allocate(const size_t size) Standard_OVERRIDE
-  {
-    Standard_Mutex::Sentry aSentry(myMutex);
-    return NCollection_IncAllocator::Allocate(size);
-  }
-
-  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_IncAllocator, NCollection_IncAllocator)
-
-private:
-  Standard_Mutex myMutex;
-};
-
-#endif
index 1279420..a5a8d22 100755 (executable)
@@ -46,7 +46,6 @@ BRepMesh_FactoryError.hxx
 BRepMesh_FastDiscret.hxx
 BRepMesh_GeomTool.cxx
 BRepMesh_GeomTool.hxx
-BRepMesh_IncAllocator.hxx
 BRepMesh_IncrementalMesh.cxx
 BRepMesh_IncrementalMesh.hxx
 BRepMesh_MeshAlgoFactory.cxx
index bd2e74c..08c07f8 100644 (file)
 // commercial license or contractual agreement.
 
 #include <BRepMeshData_Model.hxx>
+
 #include <BRepMeshData_Face.hxx>
 #include <BRepMeshData_Edge.hxx>
-#include <BRepMesh_IncAllocator.hxx>
 #include <BRepMesh_OrientedEdge.hxx>
 #include <BRepMesh_Vertex.hxx>
+#include <NCollection_IncAllocator.hxx>
 
 //=======================================================================
 // Function: Constructor
 BRepMeshData_Model::BRepMeshData_Model (const TopoDS_Shape& theShape)
   : IMeshData_Model (theShape),
     myMaxSize (0.),
-    myAllocator (new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+    myAllocator (new NCollection_IncAllocator (IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
     myDFaces (256, myAllocator),
     myDEdges (256, myAllocator)
 {
+  myAllocator->SetThreadSafe();
 }
 
 //=======================================================================
index a867afa..35ce1f6 100644 (file)
@@ -177,7 +177,8 @@ Standard_EXPORT void IncAllocator_PrintAlive()
 //purpose  : Constructor
 //=======================================================================
 
-NCollection_IncAllocator::NCollection_IncAllocator (const size_t theBlockSize)
+NCollection_IncAllocator::NCollection_IncAllocator (size_t theBlockSize)
+: myMutex (NULL)
 {
 #ifdef ALLOC_TRACK_USAGE
   printf ("\n..NCollection_IncAllocator: Created (%x)\n",this);
@@ -207,6 +208,7 @@ NCollection_IncAllocator::NCollection_IncAllocator (const size_t theBlockSize)
 
 NCollection_IncAllocator::~NCollection_IncAllocator ()
 {
+  delete myMutex;
 #ifdef OCCT_DEBUG
   if (IS_DEBUG)
     Debug_Destroy(this);
@@ -216,6 +218,24 @@ NCollection_IncAllocator::~NCollection_IncAllocator ()
 }
 
 //=======================================================================
+//function : SetThreadSafe
+//purpose  :
+//=======================================================================
+void NCollection_IncAllocator::SetThreadSafe (bool theIsThreadSafe)
+{
+  if (myMutex == NULL
+   && theIsThreadSafe)
+  {
+    myMutex = new Standard_Mutex();
+  }
+  else if (!theIsThreadSafe)
+  {
+    delete myMutex;
+    myMutex = NULL;
+  }
+}
+
+//=======================================================================
 //function : Allocate
 //purpose  : allocate a memory
 //remark   : returns NULL if allocation fails
@@ -226,6 +246,7 @@ void * NCollection_IncAllocator::Allocate (const size_t aSize)
   aligned_t * aResult = NULL;
   const size_t cSize = aSize ? IMEM_SIZE(aSize) : 0;
 
+  Standard_Mutex::Sentry aLock (myMutex);
   if (cSize > mySize) {
     /* If the requested size exceeds normal allocation size, allocate
        a separate block and place it as the head of the list              */
@@ -286,10 +307,12 @@ void * NCollection_IncAllocator::Reallocate (void         * theAddress,
 // Check that the dummy parameters are OK
   if (theAddress == NULL || oldSize == 0)
     return Allocate (newSize);
+
   const size_t cOldSize = IMEM_SIZE(oldSize);
   const size_t cNewSize = newSize ? IMEM_SIZE(newSize) : 0;
   aligned_t * anAddress = (aligned_t *) theAddress;
 
+  Standard_Mutex::Sentry aLock (myMutex);
 // We check only the LAST allocation to do the real extension/contraction
   if (anAddress + cOldSize == myFirstBlock -> p_free_space) {
     myFirstBlock -> p_free_space = anAddress;
@@ -372,6 +395,7 @@ void NCollection_IncAllocator::Clean ()
 
 void NCollection_IncAllocator::Reset (const Standard_Boolean doReleaseMem)
 {
+  Standard_Mutex::Sentry aLock (myMutex);
   if (doReleaseMem)
     Clean();
   else {
index fa6f53f..84e32f8 100644 (file)
 
 #include <NCollection_BaseAllocator.hxx>
 
+class Standard_Mutex;
+
 /**
  *  Class NCollection_IncAllocator - incremental memory  allocator. This class
  *  allocates  memory  on  request  returning  the  pointer  to  an  allocated
  *  block. This memory is never returned  to the system until the allocator is
  *  destroyed.
- *  
+ *
  *  By comparison with  the standard new() and malloc()  calls, this method is
  *  faster and consumes very small additional memory to maintain the heap.
- *  
+ *
  *  All pointers  returned by Allocate() are  aligned to the size  of the data
  *  type "aligned_t". To  modify the size of memory  blocks requested from the
  *  OS,  use the parameter  of the  constructor (measured  in bytes);  if this
  *  parameter is  smaller than  25 bytes on  32bit or  49 bytes on  64bit, the
  *  block size will be the default 24 kbytes
+ *
+ *  Note that this allocator is most suitable for single-threaded algorithms
+ *  (consider creating dedicated allocators per working thread),
+ *  and thread-safety of allocations is DISABLED by default (see SetThreadSafe()).
  */
 class NCollection_IncAllocator : public NCollection_BaseAllocator
 {
@@ -41,8 +47,13 @@ class NCollection_IncAllocator : public NCollection_BaseAllocator
 
   // ---------- PUBLIC METHODS ----------
 
-  //! Constructor
-  Standard_EXPORT NCollection_IncAllocator (const size_t theBlockSize = DefaultBlockSize);
+  //! Constructor.
+  //! Note that this constructor does NOT setup mutex for using allocator concurrently from different threads,
+  //! see SetThreadSafe() method.
+  Standard_EXPORT NCollection_IncAllocator (size_t theBlockSize = DefaultBlockSize);
+
+  //! Setup mutex for thread-safe allocations.
+  Standard_EXPORT void SetThreadSafe (bool theIsThreadSafe = true);
 
   //! Allocate memory with given size. Returns NULL on failure
   Standard_EXPORT virtual void* Allocate        (const size_t size) Standard_OVERRIDE;
@@ -105,6 +116,7 @@ class NCollection_IncAllocator : public NCollection_BaseAllocator
   };
  protected:
   // --------- PROTECTED FIELDS ---------
+  Standard_Mutex* myMutex;
   IBlock        * myFirstBlock;
   size_t        mySize;
   size_t        myMemSize;