NCollection_IncAllocator has been extended with optional mutex allocation (disabled by default).
#include <IMeshData_Edge.hxx>
#include <OSD_Parallel.hxx>
#include <BRepMesh_GeomTool.hxx>
-#include <BRepMesh_IncAllocator.hxx>
namespace
{
+++ /dev/null
-// 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
BRepMesh_FastDiscret.hxx
BRepMesh_GeomTool.cxx
BRepMesh_GeomTool.hxx
-BRepMesh_IncAllocator.hxx
BRepMesh_IncrementalMesh.cxx
BRepMesh_IncrementalMesh.hxx
BRepMesh_MeshAlgoFactory.cxx
// 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();
}
//=======================================================================
//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);
NCollection_IncAllocator::~NCollection_IncAllocator ()
{
+ delete myMutex;
#ifdef OCCT_DEBUG
if (IS_DEBUG)
Debug_Destroy(this);
free (myFirstBlock);
}
+//=======================================================================
+//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
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 */
// 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;
void NCollection_IncAllocator::Reset (const Standard_Boolean doReleaseMem)
{
+ Standard_Mutex::Sentry aLock (myMutex);
if (doReleaseMem)
Clean();
else {
#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
{
// ---------- 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;
};
protected:
// --------- PROTECTED FIELDS ---------
+ Standard_Mutex* myMutex;
IBlock * myFirstBlock;
size_t mySize;
size_t myMemSize;