mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-16 10:54:53 +03:00
0023949: OCC IncAllocator allocates second and further blocks with different size then first one
NCollection_IncAllocator tuned to allocate blocks of equal size to reduce fragmentation and increase chances for block reuse
This commit is contained in:
parent
2a141d40f0
commit
db56cc2d24
@ -185,10 +185,10 @@ NCollection_IncAllocator::NCollection_IncAllocator (const size_t theBlockSize)
|
|||||||
Debug_Create(this);
|
Debug_Create(this);
|
||||||
#endif
|
#endif
|
||||||
const size_t aSize = IMEM_SIZE(sizeof(IBlock)) +
|
const size_t aSize = IMEM_SIZE(sizeof(IBlock)) +
|
||||||
IMEM_SIZE((theBlockSize > 2*sizeof(IBlock)) ? theBlockSize : 24600);
|
IMEM_SIZE((theBlockSize > 2*sizeof(IBlock)) ? theBlockSize : DefaultBlockSize);
|
||||||
IBlock * const aBlock = (IBlock *) malloc (aSize * sizeof(aligned_t));
|
IBlock * const aBlock = (IBlock *) malloc (aSize * sizeof(aligned_t));
|
||||||
myFirstBlock = aBlock;
|
myFirstBlock = aBlock;
|
||||||
mySize = aSize;
|
mySize = aSize - IMEM_SIZE(sizeof(IBlock));
|
||||||
myMemSize = aSize * sizeof(aligned_t);
|
myMemSize = aSize * sizeof(aligned_t);
|
||||||
if (aBlock == NULL)
|
if (aBlock == NULL)
|
||||||
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
||||||
@ -229,6 +229,8 @@ void * NCollection_IncAllocator::Allocate (const size_t aSize)
|
|||||||
aResult = (aligned_t *) allocateNewBlock (cSize+1);
|
aResult = (aligned_t *) allocateNewBlock (cSize+1);
|
||||||
if (aResult)
|
if (aResult)
|
||||||
myFirstBlock -> p_free_space = myFirstBlock -> p_end_block;
|
myFirstBlock -> p_free_space = myFirstBlock -> p_end_block;
|
||||||
|
else
|
||||||
|
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
||||||
} else
|
} else
|
||||||
if (cSize <= IMEM_FREE(myFirstBlock)) {
|
if (cSize <= IMEM_FREE(myFirstBlock)) {
|
||||||
/* If the requested size fits into the free space in the 1st block */
|
/* If the requested size fits into the free space in the 1st block */
|
||||||
@ -250,6 +252,20 @@ void * NCollection_IncAllocator::Allocate (const size_t aSize)
|
|||||||
aResult = (aligned_t *) allocateNewBlock (mySize);
|
aResult = (aligned_t *) allocateNewBlock (mySize);
|
||||||
if (aResult)
|
if (aResult)
|
||||||
myFirstBlock -> p_free_space = aResult + cSize;
|
myFirstBlock -> p_free_space = aResult + cSize;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t aDefault = IMEM_SIZE(DefaultBlockSize);
|
||||||
|
if (cSize > aDefault)
|
||||||
|
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aResult = (aligned_t *) allocateNewBlock (aDefault);
|
||||||
|
if (aResult)
|
||||||
|
myFirstBlock -> p_free_space = aResult + cSize;
|
||||||
|
else
|
||||||
|
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return aResult;
|
return aResult;
|
||||||
@ -299,12 +315,17 @@ void * NCollection_IncAllocator::Reallocate (void * theAddress,
|
|||||||
// - extension of terminating allocation when the new size is too big
|
// - extension of terminating allocation when the new size is too big
|
||||||
// In both cases create a new memory block, allocate memory and copy there
|
// In both cases create a new memory block, allocate memory and copy there
|
||||||
// the reallocated memory.
|
// the reallocated memory.
|
||||||
aligned_t * aResult = (aligned_t *) allocateNewBlock (mySize);
|
size_t cMaxSize = mySize > cNewSize ? mySize : cNewSize;
|
||||||
|
aligned_t * aResult = (aligned_t *) allocateNewBlock (cMaxSize);
|
||||||
if (aResult) {
|
if (aResult) {
|
||||||
myFirstBlock -> p_free_space = aResult + cNewSize;
|
myFirstBlock -> p_free_space = aResult + cNewSize;
|
||||||
for (unsigned i = 0; i < cOldSize; i++)
|
for (unsigned i = 0; i < cOldSize; i++)
|
||||||
aResult[i] = anAddress[i];
|
aResult[i] = anAddress[i];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
||||||
|
}
|
||||||
return aResult;
|
return aResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +427,5 @@ void * NCollection_IncAllocator::allocateNewBlock (const size_t cSize)
|
|||||||
aResult = (aligned_t *) IMEM_ALIGN(&aBlock[1]);
|
aResult = (aligned_t *) IMEM_ALIGN(&aBlock[1]);
|
||||||
myMemSize += aSz * sizeof(aligned_t);
|
myMemSize += aSz * sizeof(aligned_t);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
|
|
||||||
return aResult;
|
return aResult;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class NCollection_IncAllocator : public NCollection_BaseAllocator
|
|||||||
// ---------- PUBLIC METHODS ----------
|
// ---------- PUBLIC METHODS ----------
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Standard_EXPORT NCollection_IncAllocator (const size_t theBlockSize = 24600);
|
Standard_EXPORT NCollection_IncAllocator (const size_t theBlockSize = DefaultBlockSize);
|
||||||
|
|
||||||
//! Allocate memory with given size. Returns NULL on failure
|
//! Allocate memory with given size. Returns NULL on failure
|
||||||
Standard_EXPORT virtual void* Allocate (const size_t size);
|
Standard_EXPORT virtual void* Allocate (const size_t size);
|
||||||
@ -78,6 +78,8 @@ class NCollection_IncAllocator : public NCollection_BaseAllocator
|
|||||||
Standard_EXPORT void Reset (const Standard_Boolean
|
Standard_EXPORT void Reset (const Standard_Boolean
|
||||||
doReleaseMem=Standard_True);
|
doReleaseMem=Standard_True);
|
||||||
|
|
||||||
|
static const size_t DefaultBlockSize = 24600;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct IBlock;
|
struct IBlock;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user