1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0030329: Move BRepMesh_IncAllocator to NCollection package

NCollection_IncAllocator has been extended with optional mutex allocation (disabled by default).
This commit is contained in:
kgv 2019-02-04 12:21:14 +03:00 committed by bugmaster
parent 976627e601
commit 95c882e9d4
6 changed files with 45 additions and 59 deletions

View File

@ -18,7 +18,6 @@
#include <IMeshData_Edge.hxx>
#include <OSD_Parallel.hxx>
#include <BRepMesh_GeomTool.hxx>
#include <BRepMesh_IncAllocator.hxx>
namespace
{

View File

@ -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

View File

@ -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

View File

@ -14,11 +14,12 @@
// 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
@ -27,10 +28,11 @@
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();
}
//=======================================================================

View 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);
@ -215,6 +217,24 @@ NCollection_IncAllocator::~NCollection_IncAllocator ()
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
@ -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 {

View File

@ -18,20 +18,26 @@
#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;