From df410a6192bb881f153133acc5e480b216c6246b Mon Sep 17 00:00:00 2001 From: oan Date: Mon, 16 Jan 2023 14:57:25 +0300 Subject: [PATCH] 0030329: Move BRepMesh_IncAllocator to NCollection package NCollection_IncAllocator has been extended with optional mutex allocation (disabled by default). --- src/NCollection/NCollection_IncAllocator.cxx | 26 +++++++++++++++++++- src/NCollection/NCollection_IncAllocator.hxx | 20 ++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/NCollection/NCollection_IncAllocator.cxx b/src/NCollection/NCollection_IncAllocator.cxx index a867afa4e6..35ce1f6248 100644 --- a/src/NCollection/NCollection_IncAllocator.cxx +++ b/src/NCollection/NCollection_IncAllocator.cxx @@ -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 { diff --git a/src/NCollection/NCollection_IncAllocator.hxx b/src/NCollection/NCollection_IncAllocator.hxx index fa6f53f871..84e32f8fc4 100644 --- a/src/NCollection/NCollection_IncAllocator.hxx +++ b/src/NCollection/NCollection_IncAllocator.hxx @@ -18,20 +18,26 @@ #include +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; -- 2.39.5