Added a max_size function to all AZStd container style allocator functions (#4106)

* Added a max_size function to all AZStd container style allocator
functions

The max_size functions returns the maximum value that a single contiguous
allocation value returns

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Updated the BestFitExternalMapSchema and MallocSchema
GetMaxContiguousAllocationSize function

Those functions now return a Max allocation size of
AZ_CORE_MAX_ALLOCATOR size to indicate the maximum size for a single
allocation

Changed the IAllocatorAllocator::GetMaxContiguousAllocationSize function
from a pure virtual function to regular virtual function

Removed the left over String.cpp test to validate that the issue with
the allocator::max_size() function was occuring

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
monroegm-disable-blank-issue-2
lumberyard-employee-dm 4 years ago committed by GitHub
parent 2382b5cbd3
commit 4e8d4c0c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -96,7 +96,7 @@ namespace AZ
const char* get_name() const { return m_name; } const char* get_name() const { return m_name; }
void set_name(const char* name) { m_name = name; } void set_name(const char* name) { m_name = name; }
size_type get_max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; } constexpr size_type max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
size_type get_allocated_size() const { return 0; } size_type get_allocated_size() const { return 0; }
bool is_lock_free() { return false; } bool is_lock_free() { return false; }

@ -216,6 +216,11 @@ namespace AZ
return m_source->GetMaxAllocationSize(); return m_source->GetMaxAllocationSize();
} }
auto AllocatorOverrideShim::GetMaxContiguousAllocationSize() const -> size_type
{
return m_source->GetMaxContiguousAllocationSize();
}
IAllocatorAllocate* AllocatorOverrideShim::GetSubAllocator() IAllocatorAllocate* AllocatorOverrideShim::GetSubAllocator()
{ {
return m_source->GetSubAllocator(); return m_source->GetSubAllocator();

@ -52,6 +52,7 @@ namespace AZ
size_type NumAllocatedBytes() const override; size_type NumAllocatedBytes() const override;
size_type Capacity() const override; size_type Capacity() const override;
size_type GetMaxAllocationSize() const override; size_type GetMaxAllocationSize() const override;
size_type GetMaxContiguousAllocationSize() const override;
IAllocatorAllocate* GetSubAllocator() override; IAllocatorAllocate* GetSubAllocator() override;
private: private:

@ -188,6 +188,11 @@ BestFitExternalMapAllocator::GetMaxAllocationSize() const
return m_schema->GetMaxAllocationSize(); return m_schema->GetMaxAllocationSize();
} }
auto BestFitExternalMapAllocator::GetMaxContiguousAllocationSize() const -> size_type
{
return m_schema->GetMaxContiguousAllocationSize();
}
//========================================================================= //=========================================================================
// GetSubAllocator // GetSubAllocator
// [1/28/2011] // [1/28/2011]

@ -63,6 +63,7 @@ namespace AZ
size_type NumAllocatedBytes() const override; size_type NumAllocatedBytes() const override;
size_type Capacity() const override; size_type Capacity() const override;
size_type GetMaxAllocationSize() const override; size_type GetMaxAllocationSize() const override;
size_type GetMaxContiguousAllocationSize() const override;
IAllocatorAllocate* GetSubAllocator() override; IAllocatorAllocate* GetSubAllocator() override;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

@ -136,6 +136,12 @@ BestFitExternalMapSchema::GetMaxAllocationSize() const
return 0; return 0;
} }
auto BestFitExternalMapSchema::GetMaxContiguousAllocationSize() const -> size_type
{
// Return the maximum size of any single allocation
return AZ_CORE_MAX_ALLOCATOR_SIZE;
}
//========================================================================= //=========================================================================
// GarbageCollect // GarbageCollect
// [1/28/2011] // [1/28/2011]

@ -57,6 +57,7 @@ namespace AZ
AZ_FORCE_INLINE size_type NumAllocatedBytes() const { return m_used; } AZ_FORCE_INLINE size_type NumAllocatedBytes() const { return m_used; }
AZ_FORCE_INLINE size_type Capacity() const { return m_desc.m_memoryBlockByteSize; } AZ_FORCE_INLINE size_type Capacity() const { return m_desc.m_memoryBlockByteSize; }
size_type GetMaxAllocationSize() const; size_type GetMaxAllocationSize() const;
size_type GetMaxContiguousAllocationSize() const;
AZ_FORCE_INLINE IAllocatorAllocate* GetSubAllocator() const { return m_desc.m_mapAllocator; } AZ_FORCE_INLINE IAllocatorAllocate* GetSubAllocator() const { return m_desc.m_mapAllocator; }
/** /**

@ -244,6 +244,11 @@ namespace AZ
return maxChunk; return maxChunk;
} }
auto HeapSchema::GetMaxContiguousAllocationSize() const -> size_type
{
return MAX_REQUEST;
}
AZ_FORCE_INLINE HeapSchema::size_type AZ_FORCE_INLINE HeapSchema::size_type
HeapSchema::ChunckSize(pointer_type ptr) HeapSchema::ChunckSize(pointer_type ptr)
{ {

@ -57,6 +57,7 @@ namespace AZ
virtual size_type NumAllocatedBytes() const { return m_used; } virtual size_type NumAllocatedBytes() const { return m_used; }
virtual size_type Capacity() const { return m_capacity; } virtual size_type Capacity() const { return m_capacity; }
virtual size_type GetMaxAllocationSize() const; virtual size_type GetMaxAllocationSize() const;
size_type GetMaxContiguousAllocationSize() const override;
virtual IAllocatorAllocate* GetSubAllocator() { return m_subAllocator; } virtual IAllocatorAllocate* GetSubAllocator() { return m_subAllocator; }
virtual void GarbageCollect() {} virtual void GarbageCollect() {}

@ -1069,6 +1069,7 @@ namespace AZ {
/// returns allocation size for the pointer if it belongs to the allocator. result is undefined if the pointer doesn't belong to the allocator. /// returns allocation size for the pointer if it belongs to the allocator. result is undefined if the pointer doesn't belong to the allocator.
size_t AllocationSize(void* ptr); size_t AllocationSize(void* ptr);
size_t GetMaxAllocationSize() const; size_t GetMaxAllocationSize() const;
size_t GetMaxContiguousAllocationSize() const;
size_t GetUnAllocatedMemory(bool isPrint) const; size_t GetUnAllocatedMemory(bool isPrint) const;
void* SystemAlloc(size_t size, size_t align); void* SystemAlloc(size_t size, size_t align);
@ -2301,6 +2302,11 @@ namespace AZ {
return maxSize; return maxSize;
} }
size_t HpAllocator::GetMaxContiguousAllocationSize() const
{
return AZ_CORE_MAX_ALLOCATOR_SIZE;
}
//========================================================================= //=========================================================================
// GetUnAllocatedMemory // GetUnAllocatedMemory
// [9/30/2013] // [9/30/2013]
@ -2677,6 +2683,11 @@ namespace AZ {
return m_allocator->GetMaxAllocationSize(); return m_allocator->GetMaxAllocationSize();
} }
auto HphaSchema::GetMaxContiguousAllocationSize() const -> size_type
{
return m_allocator->GetMaxContiguousAllocationSize();
}
//========================================================================= //=========================================================================
// GetUnAllocatedMemory // GetUnAllocatedMemory
// [9/30/2013] // [9/30/2013]

@ -66,6 +66,7 @@ namespace AZ
virtual size_type NumAllocatedBytes() const; virtual size_type NumAllocatedBytes() const;
virtual size_type Capacity() const; virtual size_type Capacity() const;
virtual size_type GetMaxAllocationSize() const; virtual size_type GetMaxAllocationSize() const;
size_type GetMaxContiguousAllocationSize() const override;
virtual size_type GetUnAllocatedMemory(bool isPrint = false) const; virtual size_type GetUnAllocatedMemory(bool isPrint = false) const;
virtual IAllocatorAllocate* GetSubAllocator() { return m_desc.m_subAllocator; } virtual IAllocatorAllocate* GetSubAllocator() { return m_desc.m_subAllocator; }

@ -62,6 +62,8 @@ namespace AZ
virtual size_type Capacity() const = 0; virtual size_type Capacity() const = 0;
/// Returns max allocation size if possible. If not returned value is 0 /// Returns max allocation size if possible. If not returned value is 0
virtual size_type GetMaxAllocationSize() const { return 0; } virtual size_type GetMaxAllocationSize() const { return 0; }
/// Returns the maximum contiguous allocation size of a single allocation
virtual size_type GetMaxContiguousAllocationSize() const { return 0; }
/** /**
* Returns memory allocated by the allocator and available to the user for allocations. * Returns memory allocated by the allocator and available to the user for allocations.
* IMPORTANT: this is not the overhead memory this is just the memory that is allocated, but not used. Example: the pool allocators * IMPORTANT: this is not the overhead memory this is just the memory that is allocated, but not used. Example: the pool allocators

@ -144,6 +144,11 @@ AZ::MallocSchema::size_type AZ::MallocSchema::GetMaxAllocationSize() const
return 0xFFFFFFFFull; return 0xFFFFFFFFull;
} }
AZ::MallocSchema::size_type AZ::MallocSchema::GetMaxContiguousAllocationSize() const
{
return AZ_CORE_MAX_ALLOCATOR_SIZE;
}
AZ::IAllocatorAllocate* AZ::MallocSchema::GetSubAllocator() AZ::IAllocatorAllocate* AZ::MallocSchema::GetSubAllocator()
{ {
return nullptr; return nullptr;

@ -50,6 +50,7 @@ namespace AZ
virtual size_type NumAllocatedBytes() const override; virtual size_type NumAllocatedBytes() const override;
virtual size_type Capacity() const override; virtual size_type Capacity() const override;
virtual size_type GetMaxAllocationSize() const override; virtual size_type GetMaxAllocationSize() const override;
virtual size_type GetMaxContiguousAllocationSize() const override;
virtual IAllocatorAllocate* GetSubAllocator() override; virtual IAllocatorAllocate* GetSubAllocator() override;
virtual void GarbageCollect() override; virtual void GarbageCollect() override;

@ -839,6 +839,11 @@ namespace AZ
return AZ::AllocatorInstance<Parent>::Get().GetMaxAllocationSize(); return AZ::AllocatorInstance<Parent>::Get().GetMaxAllocationSize();
} }
size_type GetMaxContiguousAllocationSize() const override
{
return AZ::AllocatorInstance<Parent>::Get().GetMaxContiguousAllocationSize();
}
size_type GetUnAllocatedMemory(bool isPrint = false) const override size_type GetUnAllocatedMemory(bool isPrint = false) const override
{ {
return AZ::AllocatorInstance<Parent>::Get().GetUnAllocatedMemory(isPrint); return AZ::AllocatorInstance<Parent>::Get().GetUnAllocatedMemory(isPrint);
@ -896,7 +901,7 @@ namespace AZ
} }
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
size_type get_max_size() const { return AllocatorInstance<Allocator>::Get().GetMaxAllocationSize(); } size_type max_size() const { return AllocatorInstance<Allocator>::Get().GetMaxContiguousAllocationSize(); }
size_type get_allocated_size() const { return AllocatorInstance<Allocator>::Get().NumAllocatedBytes(); } size_type get_allocated_size() const { return AllocatorInstance<Allocator>::Get().NumAllocatedBytes(); }
AZ_FORCE_INLINE bool is_lock_free() { return AllocatorInstance<Allocator>::Get().is_lock_free(); } AZ_FORCE_INLINE bool is_lock_free() { return AllocatorInstance<Allocator>::Get().is_lock_free(); }
@ -954,7 +959,7 @@ namespace AZ
} }
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
size_type get_max_size() const { return m_allocator->GetMaxAllocationSize(); } size_type max_size() const { return m_allocator->GetMaxContiguousAllocationSize(); }
size_type get_allocated_size() const { return m_allocator->NumAllocatedBytes(); } size_type get_allocated_size() const { return m_allocator->NumAllocatedBytes(); }
AZ_FORCE_INLINE bool operator==(const AZStdIAllocator& rhs) const { return m_allocator == rhs.m_allocator; } AZ_FORCE_INLINE bool operator==(const AZStdIAllocator& rhs) const { return m_allocator == rhs.m_allocator; }
@ -1006,7 +1011,7 @@ namespace AZ
} }
constexpr const char* get_name() const { return m_name; } constexpr const char* get_name() const { return m_name; }
void set_name(const char* name) { m_name = name; } void set_name(const char* name) { m_name = name; }
size_type get_max_size() const { return m_allocatorFunctor().GetMaxAllocationSize(); } size_type max_size() const { return m_allocatorFunctor().GetMaxContiguousAllocationSize(); }
size_type get_allocated_size() const { return m_allocatorFunctor().NumAllocatedBytes(); } size_type get_allocated_size() const { return m_allocatorFunctor().NumAllocatedBytes(); }
constexpr bool operator==(const AZStdFunctorAllocator& rhs) const { return m_allocatorFunctor == rhs.m_allocatorFunctor; } constexpr bool operator==(const AZStdFunctorAllocator& rhs) const { return m_allocatorFunctor == rhs.m_allocatorFunctor; }

@ -61,6 +61,7 @@ namespace AZ
size_type NumAllocatedBytes() const override { return m_custom ? m_custom->NumAllocatedBytes() : m_numAllocatedBytes; } size_type NumAllocatedBytes() const override { return m_custom ? m_custom->NumAllocatedBytes() : m_numAllocatedBytes; }
size_type Capacity() const override { return m_custom ? m_custom->Capacity() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited size_type Capacity() const override { return m_custom ? m_custom->Capacity() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
size_type GetMaxAllocationSize() const override { return m_custom ? m_custom->GetMaxAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited size_type GetMaxAllocationSize() const override { return m_custom ? m_custom->GetMaxAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
size_type GetMaxContiguousAllocationSize() const override { return m_custom ? m_custom->GetMaxContiguousAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
IAllocatorAllocate* GetSubAllocator() override { return m_custom ? m_custom : NULL; } IAllocatorAllocate* GetSubAllocator() override { return m_custom ? m_custom : NULL; }
protected: protected:

@ -232,6 +232,7 @@ namespace AZ
size_type NumAllocatedBytes() const; size_type NumAllocatedBytes() const;
size_type Capacity() const; size_type Capacity() const;
size_type GetMaxAllocationSize() const; size_type GetMaxAllocationSize() const;
size_type GetMaxContiguousAllocationSize() const;
IAllocatorAllocate* GetSubAllocator(); IAllocatorAllocate* GetSubAllocator();
void GarbageCollect(); void GarbageCollect();
@ -674,6 +675,11 @@ AZ::OverrunDetectionSchema::size_type AZ::OverrunDetectionSchemaImpl::GetMaxAllo
return 0; return 0;
} }
auto AZ::OverrunDetectionSchemaImpl::GetMaxContiguousAllocationSize() const -> size_type
{
return 0;
}
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchemaImpl::GetSubAllocator() AZ::IAllocatorAllocate* AZ::OverrunDetectionSchemaImpl::GetSubAllocator()
{ {
return nullptr; return nullptr;
@ -799,6 +805,11 @@ AZ::OverrunDetectionSchema::size_type AZ::OverrunDetectionSchema::GetMaxAllocati
return m_impl->GetMaxAllocationSize(); return m_impl->GetMaxAllocationSize();
} }
auto AZ::OverrunDetectionSchema::GetMaxContiguousAllocationSize() const -> size_type
{
return m_impl->GetMaxContiguousAllocationSize();
}
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchema::GetSubAllocator() AZ::IAllocatorAllocate* AZ::OverrunDetectionSchema::GetSubAllocator()
{ {
return m_impl->GetSubAllocator(); return m_impl->GetSubAllocator();

@ -86,6 +86,7 @@ namespace AZ
virtual size_type NumAllocatedBytes() const override; virtual size_type NumAllocatedBytes() const override;
virtual size_type Capacity() const override; virtual size_type Capacity() const override;
virtual size_type GetMaxAllocationSize() const override; virtual size_type GetMaxAllocationSize() const override;
size_type GetMaxContiguousAllocationSize() const override;
virtual IAllocatorAllocate* GetSubAllocator() override; virtual IAllocatorAllocate* GetSubAllocator() override;
virtual void GarbageCollect() override; virtual void GarbageCollect() override;

@ -707,6 +707,11 @@ PoolSchema::GarbageCollect()
//m_impl->GarbageCollect(); //m_impl->GarbageCollect();
} }
auto PoolSchema::GetMaxContiguousAllocationSize() const -> size_type
{
return m_impl->m_allocator.m_maxAllocationSize;
}
//========================================================================= //=========================================================================
// NumAllocatedBytes // NumAllocatedBytes
// [11/1/2010] // [11/1/2010]
@ -1052,6 +1057,11 @@ ThreadPoolSchema::GarbageCollect()
m_impl->GarbageCollect(); m_impl->GarbageCollect();
} }
auto ThreadPoolSchema::GetMaxContiguousAllocationSize() const -> size_type
{
return m_impl->m_maxAllocationSize;
}
//========================================================================= //=========================================================================
// NumAllocatedBytes // NumAllocatedBytes
// [11/1/2010] // [11/1/2010]

@ -70,6 +70,7 @@ namespace AZ
/// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations. /// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations.
void GarbageCollect() override; void GarbageCollect() override;
size_type GetMaxContiguousAllocationSize() const override;
size_type NumAllocatedBytes() const override; size_type NumAllocatedBytes() const override;
size_type Capacity() const override; size_type Capacity() const override;
IAllocatorAllocate* GetSubAllocator() override; IAllocatorAllocate* GetSubAllocator() override;
@ -115,6 +116,7 @@ namespace AZ
/// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations. /// Return unused memory to the OS. Don't call this too often because you will force unnecessary allocations.
void GarbageCollect() override; void GarbageCollect() override;
size_type GetMaxContiguousAllocationSize() const override;
size_type NumAllocatedBytes() const override; size_type NumAllocatedBytes() const override;
size_type Capacity() const override; size_type Capacity() const override;
IAllocatorAllocate* GetSubAllocator() override; IAllocatorAllocate* GetSubAllocator() override;

@ -179,6 +179,11 @@ namespace AZ
return m_schema->GetMaxAllocationSize(); return m_schema->GetMaxAllocationSize();
} }
size_type GetMaxContiguousAllocationSize() const override
{
return m_schema->GetMaxContiguousAllocationSize();
}
size_type GetUnAllocatedMemory(bool isPrint = false) const override size_type GetUnAllocatedMemory(bool isPrint = false) const override
{ {
return m_schema->GetUnAllocatedMemory(isPrint); return m_schema->GetUnAllocatedMemory(isPrint);

@ -103,6 +103,7 @@ namespace AZ
size_type Capacity() const override { return m_allocator->Capacity(); } size_type Capacity() const override { return m_allocator->Capacity(); }
/// Keep in mind this operation will execute GarbageCollect to make sure it returns, max allocation. This function WILL be slow. /// Keep in mind this operation will execute GarbageCollect to make sure it returns, max allocation. This function WILL be slow.
size_type GetMaxAllocationSize() const override { return m_allocator->GetMaxAllocationSize(); } size_type GetMaxAllocationSize() const override { return m_allocator->GetMaxAllocationSize(); }
size_type GetMaxContiguousAllocationSize() const override { return m_allocator->GetMaxContiguousAllocationSize(); }
size_type GetUnAllocatedMemory(bool isPrint = false) const override { return m_allocator->GetUnAllocatedMemory(isPrint); } size_type GetUnAllocatedMemory(bool isPrint = false) const override { return m_allocator->GetUnAllocatedMemory(isPrint); }
IAllocatorAllocate* GetSubAllocator() override { return m_isCustom ? m_allocator : m_allocator->GetSubAllocator(); } IAllocatorAllocate* GetSubAllocator() override { return m_isCustom ? m_allocator : m_allocator->GetSubAllocator(); }

@ -61,7 +61,7 @@ namespace AZ
const char* get_name() const { return m_name; } const char* get_name() const { return m_name; }
void set_name(const char* name) { m_name = name; } void set_name(const char* name) { m_name = name; }
size_type get_max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; } constexpr size_type max_size() const { return AZ_CORE_MAX_ALLOCATOR_SIZE; }
size_type get_allocated_size() const { return 0; } size_type get_allocated_size() const { return 0; }
bool is_lock_free() { return false; } bool is_lock_free() { return false; }

@ -2306,7 +2306,7 @@ LUA_API const Node* lua_getDummyNode()
else // even references are stored by value as we need to convert from lua native type, i.e. there is not real reference for NativeTypes (numbers, strings, etc.) else // even references are stored by value as we need to convert from lua native type, i.e. there is not real reference for NativeTypes (numbers, strings, etc.)
{ {
bool usedBackupAlloc = false; bool usedBackupAlloc = false;
if (backupAllocator != nullptr && sizeof(T) > tempAllocator.get_max_size()) if (backupAllocator != nullptr && sizeof(T) > AZStd::allocator_traits<decltype(tempAllocator)>::max_size(tempAllocator))
{ {
value.m_value = backupAllocator->allocate(sizeof(T), AZStd::alignment_of<T>::value, 0); value.m_value = backupAllocator->allocate(sizeof(T), AZStd::alignment_of<T>::value, 0);
usedBackupAlloc = true; usedBackupAlloc = true;
@ -2340,7 +2340,7 @@ LUA_API const Node* lua_getDummyNode()
else // it's a value type else // it's a value type
{ {
bool usedBackupAlloc = false; bool usedBackupAlloc = false;
if (backupAllocator != nullptr && valueClass->m_size > tempAllocator.get_max_size()) if (backupAllocator != nullptr && valueClass->m_size > AZStd::allocator_traits<decltype(tempAllocator)>::max_size(tempAllocator))
{ {
value.m_value = backupAllocator->allocate(valueClass->m_size, valueClass->m_alignment, 0); value.m_value = backupAllocator->allocate(valueClass->m_size, valueClass->m_alignment, 0);
usedBackupAlloc = true; usedBackupAlloc = true;

@ -45,7 +45,7 @@ namespace UnitTest
virtual ~AllocatorsBase() = default; virtual ~AllocatorsBase() = default;
void SetupAllocator() void SetupAllocator(const AZ::SystemAllocator::Descriptor& allocatorDesc = {})
{ {
m_drillerManager = AZ::Debug::DrillerManager::Create(); m_drillerManager = AZ::Debug::DrillerManager::Create();
m_drillerManager->Register(aznew AZ::Debug::MemoryDriller); m_drillerManager->Register(aznew AZ::Debug::MemoryDriller);
@ -54,7 +54,7 @@ namespace UnitTest
// Only create the SystemAllocator if it s not ready // Only create the SystemAllocator if it s not ready
if (!AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady()) if (!AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady())
{ {
AZ::AllocatorInstance<AZ::SystemAllocator>::Create(); AZ::AllocatorInstance<AZ::SystemAllocator>::Create(allocatorDesc);
m_ownsAllocator = true; m_ownsAllocator = true;
} }
} }
@ -85,6 +85,7 @@ namespace UnitTest
{ {
public: public:
ScopedAllocatorSetupFixture() { SetupAllocator(); } ScopedAllocatorSetupFixture() { SetupAllocator(); }
explicit ScopedAllocatorSetupFixture(const AZ::SystemAllocator::Descriptor& allocatorDesc) { SetupAllocator(allocatorDesc); }
~ScopedAllocatorSetupFixture() { TeardownAllocator(); } ~ScopedAllocatorSetupFixture() { TeardownAllocator(); }
}; };

@ -40,15 +40,11 @@ namespace AZStd
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().Resize(ptr, newSize); return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().Resize(ptr, newSize);
} }
//========================================================================= auto allocator::max_size() const -> size_type
// get_max_size
// [1/1/2008]
//=========================================================================
allocator::size_type
allocator::get_max_size() const
{ {
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().GetMaxAllocationSize(); return AZ::AllocatorInstance<AZ::SystemAllocator>::Get().GetMaxContiguousAllocationSize();
} }
//========================================================================= //=========================================================================
// get_allocated_size // get_allocated_size
// [1/1/2008] // [1/1/2008]

@ -49,8 +49,8 @@ namespace AZStd
* const char* get_name() const; * const char* get_name() const;
* void set_name(const char* name); * void set_name(const char* name);
* *
* // Returns maximum size we can allocate from this allocator. * // Returns theoretical maximum size of a single contiguous allocation from this allocator.
* size_type get_max_size() const; * size_type max_size() const;
* <optional> size_type get_allocated_size() const; * <optional> size_type get_allocated_size() const;
* }; * };
* *
@ -100,7 +100,8 @@ namespace AZStd
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0); pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0);
void deallocate(pointer_type ptr, size_type byteSize, size_type alignment); void deallocate(pointer_type ptr, size_type byteSize, size_type alignment);
size_type resize(pointer_type ptr, size_type newSize); size_type resize(pointer_type ptr, size_type newSize);
size_type get_max_size() const; // max_size actually returns the true maximum size of a single allocation
size_type max_size() const;
size_type get_allocated_size() const; size_type get_allocated_size() const;
AZ_FORCE_INLINE bool is_lock_free() { return false; } AZ_FORCE_INLINE bool is_lock_free() { return false; }
@ -157,7 +158,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const; AZ_FORCE_INLINE const char* get_name() const;
AZ_FORCE_INLINE void set_name(const char* name); AZ_FORCE_INLINE void set_name(const char* name);
AZ_FORCE_INLINE size_type get_max_size() const; AZ_FORCE_INLINE size_type max_size() const;
AZ_FORCE_INLINE bool is_lock_free(); AZ_FORCE_INLINE bool is_lock_free();
AZ_FORCE_INLINE bool is_stale_read_allowed(); AZ_FORCE_INLINE bool is_stale_read_allowed();

@ -41,7 +41,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
AZ_FORCE_INLINE size_type get_max_size() const { return m_allocator->get_max_size(); } constexpr size_type max_size() const { return m_allocator->max_size(); }
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_allocator->get_allocated_size(); } AZ_FORCE_INLINE size_type get_allocated_size() const { return m_allocator->get_allocated_size(); }

@ -59,7 +59,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
AZ_FORCE_INLINE size_type get_max_size() const { return m_size - (m_freeData - m_data); } constexpr size_type max_size() const { return m_size; }
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - m_data; } AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - m_data; }
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0) pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0)

@ -63,7 +63,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
AZ_FORCE_INLINE size_type get_max_size() const { return Size - (m_freeData - reinterpret_cast<const char*>(&m_data)); } constexpr size_type max_size() const { return Size; }
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - reinterpret_cast<const char*>(&m_data); } AZ_FORCE_INLINE size_type get_allocated_size() const { return m_freeData - reinterpret_cast<const char*>(&m_data); }
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0) pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0)
@ -190,7 +190,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
AZ_FORCE_INLINE size_type get_max_size() const { return (NumNodes - m_numOfAllocatedNodes) * sizeof(Node); } constexpr size_type max_size() const { return NumNodes * sizeof(Node); }
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes * sizeof(Node); } AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes * sizeof(Node); }
inline Node* allocate() inline Node* allocate()

@ -6,11 +6,10 @@
* *
*/ */
#pragma once #pragma once
#ifndef AZSTD_DEQUE_H
#define AZSTD_DEQUE_H 1
#include <AzCore/std/allocator.h> #include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h> #include <AzCore/std/algorithm.h>
#include <AzCore/std/createdestroy.h> #include <AzCore/std/createdestroy.h>
#include <AzCore/std/typetraits/aligned_storage.h> #include <AzCore/std/typetraits/aligned_storage.h>
@ -350,7 +349,7 @@ namespace AZStd
} }
AZ_FORCE_INLINE size_type size() const { return m_size; } AZ_FORCE_INLINE size_type size() const { return m_size; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.get_max_size() / sizeof(block_node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(block_node_type); }
AZ_FORCE_INLINE bool empty() const { return m_size == 0; } AZ_FORCE_INLINE bool empty() const { return m_size == 0; }
AZ_FORCE_INLINE const_reference at(size_type offset) const { return *const_iterator(AZSTD_CHECKED_ITERATOR_2(const_iterator_impl, m_firstOffset + offset, this)); } AZ_FORCE_INLINE const_reference at(size_type offset) const { return *const_iterator(AZSTD_CHECKED_ITERATOR_2(const_iterator_impl, m_firstOffset + offset, this)); }
@ -1243,5 +1242,3 @@ namespace AZStd
return removedCount; return removedCount;
} }
} }
#endif // AZSTD_DEQUE_H

@ -286,7 +286,7 @@ namespace AZStd
} }
AZ_FORCE_INLINE size_type size() const { return m_numElements; } AZ_FORCE_INLINE size_type size() const { return m_numElements; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); } AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); }
AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); } AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); }

@ -5,11 +5,11 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
* *
*/ */
#ifndef AZSTD_LIST_H
#define AZSTD_LIST_H 1
#pragma once #pragma once
#include <AzCore/std/allocator.h> #include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h> #include <AzCore/std/algorithm.h>
#include <AzCore/std/createdestroy.h> #include <AzCore/std/createdestroy.h>
#include <AzCore/std/typetraits/alignment_of.h> #include <AzCore/std/typetraits/alignment_of.h>
@ -316,7 +316,7 @@ namespace AZStd
} }
AZ_FORCE_INLINE size_type size() const { return m_numElements; } AZ_FORCE_INLINE size_type size() const { return m_numElements; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); } AZ_FORCE_INLINE bool empty() const { return (m_numElements == 0); }
AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); } AZ_FORCE_INLINE iterator begin() { return iterator(AZSTD_CHECKED_ITERATOR(iterator_impl, m_head.m_next)); }
@ -1346,5 +1346,3 @@ namespace AZStd
return container.remove_if(predicate); return container.remove_if(predicate);
} }
} }
#endif // AZSTD_LIST_H

@ -484,7 +484,7 @@ namespace AZStd
AZ_FORCE_INLINE bool empty() const { return m_numElements == 0; } AZ_FORCE_INLINE bool empty() const { return m_numElements == 0; }
AZ_FORCE_INLINE size_type size() const { return m_numElements; } AZ_FORCE_INLINE size_type size() const { return m_numElements; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
rbtree(this_type&& rhs) rbtree(this_type&& rhs)
: m_numElements(0) // it will be set during swap : m_numElements(0) // it will be set during swap

@ -5,10 +5,11 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
* *
*/ */
#ifndef AZSTD_RINGBUFFER_H
#define AZSTD_RINGBUFFER_H 1 #pragma once
#include <AzCore/std/allocator.h> #include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h> #include <AzCore/std/algorithm.h>
#include <AzCore/std/createdestroy.h> #include <AzCore/std/createdestroy.h>
#include <AzCore/std/utils.h> #include <AzCore/std/utils.h>
@ -416,7 +417,7 @@ namespace AZStd
} }
AZ_FORCE_INLINE size_type size() const { return m_size; } AZ_FORCE_INLINE size_type size() const { return m_size; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.max_size() / sizeof(node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
AZ_FORCE_INLINE bool empty() const { return m_size == 0; } AZ_FORCE_INLINE bool empty() const { return m_size == 0; }
AZ_FORCE_INLINE bool full() const { return size_type(m_end - m_buff) == m_size; } AZ_FORCE_INLINE bool full() const { return size_type(m_end - m_buff) == m_size; }
AZ_FORCE_INLINE size_type free() const { return size_type(m_end - m_buff) - m_size; } AZ_FORCE_INLINE size_type free() const { return size_type(m_end - m_buff) - m_size; }
@ -1240,6 +1241,3 @@ namespace AZStd
lhs.swap(rhs); lhs.swap(rhs);
} }
} }
#endif // AZSTD_RINGBUFFER_H
#pragma once

@ -9,6 +9,7 @@
#include <AzCore/std/allocator.h> #include <AzCore/std/allocator.h>
#include <AzCore/std/algorithm.h> #include <AzCore/std/algorithm.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/createdestroy.h> #include <AzCore/std/createdestroy.h>
#include <AzCore/std/typetraits/alignment_of.h> #include <AzCore/std/typetraits/alignment_of.h>
#include <AzCore/std/typetraits/is_integral.h> #include <AzCore/std/typetraits/is_integral.h>
@ -431,7 +432,7 @@ namespace AZStd
} }
AZ_FORCE_INLINE size_type size() const { return m_last - m_start; } AZ_FORCE_INLINE size_type size() const { return m_last - m_start; }
AZ_FORCE_INLINE size_type max_size() const { return m_allocator.get_max_size() / sizeof(node_type); } AZ_FORCE_INLINE size_type max_size() const { return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(node_type); }
AZ_FORCE_INLINE bool empty() const { return m_start == m_last; } AZ_FORCE_INLINE bool empty() const { return m_start == m_last; }
void reserve(size_type numElements) void reserve(size_type numElements)

@ -22,7 +22,7 @@ namespace AZStd
* Internally the buffer is allocated using aligned_storage. * Internally the buffer is allocated using aligned_storage.
* \note only allocate/deallocate are thread safe. * \note only allocate/deallocate are thread safe.
* reset, leak_before_destroy and comparison operators are not thread safe. * reset, leak_before_destroy and comparison operators are not thread safe.
* get_max_size and get_allocated_size are thread safe but the returned value is not perfectly in * get_allocated_size is thread safe but the returned value is not perfectly in
* sync on the actual number of allocations (the number of allocations is incremented before the * sync on the actual number of allocations (the number of allocations is incremented before the
* allocation happens and decremented after the allocation happens, trying to give a conservative * allocation happens and decremented after the allocation happens, trying to give a conservative
* number) * number)
@ -71,7 +71,7 @@ namespace AZStd
AZ_FORCE_INLINE const char* get_name() const { return m_name; } AZ_FORCE_INLINE const char* get_name() const { return m_name; }
AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; } AZ_FORCE_INLINE void set_name(const char* name) { m_name = name; }
AZ_FORCE_INLINE size_type get_max_size() const { return (NumNodes - m_numOfAllocatedNodes.load(AZStd::memory_order_relaxed)) * sizeof(Node); } constexpr size_type max_size() const { return NumNodes * sizeof(Node); }
AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes.load(AZStd::memory_order_relaxed) * sizeof(Node); } AZ_FORCE_INLINE size_type get_allocated_size() const { return m_numOfAllocatedNodes.load(AZStd::memory_order_relaxed) * sizeof(Node); }
inline Node* allocate() inline Node* allocate()

@ -16,6 +16,7 @@
#include <AzCore/std/base.h> #include <AzCore/std/base.h>
#include <AzCore/std/iterator.h> #include <AzCore/std/iterator.h>
#include <AzCore/std/allocator.h> #include <AzCore/std/allocator.h>
#include <AzCore/std/allocator_traits.h>
#include <AzCore/std/algorithm.h> #include <AzCore/std/algorithm.h>
#include <AzCore/std/typetraits/alignment_of.h> #include <AzCore/std/typetraits/alignment_of.h>
#include <AzCore/std/typetraits/is_integral.h> #include <AzCore/std/typetraits/is_integral.h>
@ -862,8 +863,7 @@ namespace AZStd
inline size_type max_size() const inline size_type max_size() const
{ {
// return maximum possible length of sequence // return maximum possible length of sequence
size_type num = m_allocator.get_max_size(); return AZStd::allocator_traits<allocator_type>::max_size(m_allocator) / sizeof(value_type);
return (num <= 1 ? 1 : num - 1);
} }
inline void resize(size_type newSize) inline void resize(size_type newSize)

@ -122,8 +122,15 @@ namespace UnitTest
TEST_F(AllocatorDefaultTest, AllocatorTraitsMaxSizeCompilesWithoutErrors) TEST_F(AllocatorDefaultTest, AllocatorTraitsMaxSizeCompilesWithoutErrors)
{ {
using AZStdAllocatorTraits = AZStd::allocator_traits<AZStd::allocator>; struct AllocatorWithGetMaxSize
AZStd::allocator testAllocator("trait allocator"); : AZStd::allocator
{
using AZStd::allocator::allocator;
size_t get_max_size() { return max_size(); }
};
using AZStdAllocatorTraits = AZStd::allocator_traits<AllocatorWithGetMaxSize>;
AllocatorWithGetMaxSize testAllocator("trait allocator");
typename AZStdAllocatorTraits::size_type maxSize = AZStdAllocatorTraits::max_size(testAllocator); typename AZStdAllocatorTraits::size_type maxSize = AZStdAllocatorTraits::max_size(testAllocator);
EXPECT_EQ(testAllocator.get_max_size(), maxSize); EXPECT_EQ(testAllocator.get_max_size(), maxSize);
} }
@ -149,32 +156,32 @@ namespace UnitTest
myalloc.set_name(newName); myalloc.set_name(newName);
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0); AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize)); EXPECT_EQ(bufferSize, myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
buffer_alloc_type::pointer_type data = myalloc.allocate(100, 1); buffer_alloc_type::pointer_type data = myalloc.allocate(100, 1);
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100); EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
myalloc.deallocate(data, 100, 1); // we can free the last allocation only myalloc.deallocate(data, 100, 1); // we can free the last allocation only
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize); EXPECT_EQ(bufferSize, myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
data = myalloc.allocate(100, 1); data = myalloc.allocate(100, 1);
myalloc.allocate(3, 1); myalloc.allocate(3, 1);
myalloc.deallocate(data); // can't free allocation which is not the last. myalloc.deallocate(data); // can't free allocation which is not the last.
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 103); EXPECT_EQ(bufferSize - 103, myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 103); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 103);
myalloc.reset(); myalloc.reset();
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize)); EXPECT_EQ(bufferSize, myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
data = myalloc.allocate(50, 64); data = myalloc.allocate(50, 64);
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0); AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0);
AZ_TEST_ASSERT(myalloc.get_max_size() <= bufferSize - 50); EXPECT_LE(myalloc.max_size() - myalloc.get_allocated_size(), bufferSize - 50);
AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50); AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50);
buffer_alloc_type myalloc2; buffer_alloc_type myalloc2;
@ -194,28 +201,28 @@ namespace UnitTest
myalloc.set_name(newName); myalloc.set_name(newName);
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0); AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
AZ_TEST_ASSERT(myalloc.get_max_size() == sizeof(int) * numNodes); EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
int* data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1)); int* data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1));
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(myalloc.get_max_size() == (numNodes - 1) * sizeof(int)); EXPECT_EQ((numNodes - 1) * sizeof(int), myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == sizeof(int)); AZ_TEST_ASSERT(myalloc.get_allocated_size() == sizeof(int));
myalloc.deallocate(data, sizeof(int), 1); myalloc.deallocate(data, sizeof(int), 1);
AZ_TEST_ASSERT(myalloc.get_max_size() == sizeof(int) * numNodes); EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
for (int i = 0; i < numNodes; ++i) for (int i = 0; i < numNodes; ++i)
{ {
data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1)); data = reinterpret_cast<int*>(myalloc.allocate(sizeof(int), 1));
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(myalloc.get_max_size() == (numNodes - (i + 1)) * sizeof(int)); EXPECT_EQ((numNodes - (i + 1)) * sizeof(int), myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == (i + 1) * sizeof(int)); AZ_TEST_ASSERT(myalloc.get_allocated_size() == (i + 1) * sizeof(int));
} }
myalloc.reset(); myalloc.reset();
AZ_TEST_ASSERT(myalloc.get_max_size() == numNodes * sizeof(int)); EXPECT_EQ(numNodes * sizeof(int), myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
AZ_TEST_ASSERT(myalloc == myalloc); AZ_TEST_ASSERT(myalloc == myalloc);
@ -233,7 +240,7 @@ namespace UnitTest
AZ_TEST_ASSERT(aligned_data != nullptr); AZ_TEST_ASSERT(aligned_data != nullptr);
AZ_TEST_ASSERT(((AZStd::size_t)aligned_data & (dataAlignment - 1)) == 0); AZ_TEST_ASSERT(((AZStd::size_t)aligned_data & (dataAlignment - 1)) == 0);
AZ_TEST_ASSERT(myaligned_pool.get_max_size() == (numNodes - 1) * sizeof(aligned_int_type)); EXPECT_EQ((numNodes - 1) * sizeof(aligned_int_type), myaligned_pool.max_size() - myaligned_pool.get_allocated_size());
AZ_TEST_ASSERT(myaligned_pool.get_allocated_size() == sizeof(aligned_int_type)); AZ_TEST_ASSERT(myaligned_pool.get_allocated_size() == sizeof(aligned_int_type));
myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated. myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated.
@ -268,32 +275,32 @@ namespace UnitTest
ref_allocator_type::pointer_type data1 = ref_allocator1.allocate(10, 1); ref_allocator_type::pointer_type data1 = ref_allocator1.allocate(10, 1);
AZ_TEST_ASSERT(data1 != nullptr); AZ_TEST_ASSERT(data1 != nullptr);
AZ_TEST_ASSERT(ref_allocator1.get_max_size() == bufferSize - 10); EXPECT_EQ(bufferSize - 10, ref_allocator1.max_size() - ref_allocator1.get_allocated_size());
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() == 10); AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() == 10);
AZ_TEST_ASSERT(shared_allocator.get_max_size() == bufferSize - 10); EXPECT_EQ(bufferSize - 10, shared_allocator.max_size() - shared_allocator.get_allocated_size());
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() == 10); AZ_TEST_ASSERT(shared_allocator.get_allocated_size() == 10);
ref_allocator_type::pointer_type data2 = ref_allocator2.allocate(10, 1); ref_allocator_type::pointer_type data2 = ref_allocator2.allocate(10, 1);
AZ_TEST_ASSERT(data2 != nullptr); AZ_TEST_ASSERT(data2 != nullptr);
AZ_TEST_ASSERT(ref_allocator2.get_max_size() <= bufferSize - 20); EXPECT_LE(ref_allocator2.max_size() - ref_allocator2.get_allocated_size(), bufferSize - 20);
AZ_TEST_ASSERT(ref_allocator2.get_allocated_size() >= 20); AZ_TEST_ASSERT(ref_allocator2.get_allocated_size() >= 20);
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 20); EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 20);
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20); AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20);
shared_allocator.reset(); shared_allocator.reset();
data1 = ref_allocator1.allocate(10, 32); data1 = ref_allocator1.allocate(10, 32);
AZ_TEST_ASSERT(data1 != nullptr); AZ_TEST_ASSERT(data1 != nullptr);
AZ_TEST_ASSERT(ref_allocator1.get_max_size() <= bufferSize - 10); EXPECT_LE(ref_allocator1.max_size() - ref_allocator1.get_allocated_size(), bufferSize - 10);
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 10); AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 10);
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 10); EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 10);
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 10); AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 10);
data2 = ref_allocator2.allocate(10, 32); data2 = ref_allocator2.allocate(10, 32);
AZ_TEST_ASSERT(data2 != nullptr); AZ_TEST_ASSERT(data2 != nullptr);
AZ_TEST_ASSERT(ref_allocator1.get_max_size() <= bufferSize - 20); EXPECT_LE(ref_allocator1.max_size() - ref_allocator1.get_allocated_size(), bufferSize - 20);
AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 20); AZ_TEST_ASSERT(ref_allocator1.get_allocated_size() >= 20);
AZ_TEST_ASSERT(shared_allocator.get_max_size() <= bufferSize - 20); EXPECT_LE(shared_allocator.max_size() - shared_allocator.get_allocated_size(), bufferSize - 20);
AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20); AZ_TEST_ASSERT(shared_allocator.get_allocated_size() >= 20);
AZ_TEST_ASSERT(ref_allocator1 == ref_allocator2); AZ_TEST_ASSERT(ref_allocator1 == ref_allocator2);
@ -312,31 +319,31 @@ namespace UnitTest
myalloc.set_name(newName); myalloc.set_name(newName);
AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0); AZ_TEST_ASSERT(strcmp(myalloc.get_name(), newName) == 0);
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize)); EXPECT_EQ(bufferSize, myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
stack_allocator::pointer_type data = myalloc.allocate(100, 1); stack_allocator::pointer_type data = myalloc.allocate(100, 1);
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100); EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
myalloc.deallocate(data, 100, 1); // this allocator doesn't free data myalloc.deallocate(data, 100, 1); // this allocator doesn't free data
AZ_TEST_ASSERT(myalloc.get_max_size() == bufferSize - 100); EXPECT_EQ(bufferSize - 100, myalloc.max_size() - myalloc.get_allocated_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 100);
myalloc.reset(); myalloc.reset();
AZ_TEST_ASSERT(myalloc.get_max_size() == AZStd::size_t(bufferSize)); EXPECT_EQ(bufferSize, myalloc.max_size());
AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0); AZ_TEST_ASSERT(myalloc.get_allocated_size() == 0);
data = myalloc.allocate(50, 64); data = myalloc.allocate(50, 64);
AZ_TEST_ASSERT(data != nullptr); AZ_TEST_ASSERT(data != nullptr);
AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0); AZ_TEST_ASSERT(((AZStd::size_t)data & 63) == 0);
AZ_TEST_ASSERT(myalloc.get_max_size() <= bufferSize - 50); EXPECT_LE(myalloc.max_size() - myalloc.get_allocated_size(), bufferSize - 50);
AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50); AZ_TEST_ASSERT(myalloc.get_allocated_size() >= 50);
AZ_STACK_ALLOCATOR(myalloc2, 200); // test the macro declaration AZ_STACK_ALLOCATOR(myalloc2, 200); // test the macro declaration
AZ_TEST_ASSERT(myalloc2.get_max_size() == 200); EXPECT_EQ(200, myalloc2.max_size() );
AZ_TEST_ASSERT(myalloc == myalloc); AZ_TEST_ASSERT(myalloc == myalloc);
AZ_TEST_ASSERT((myalloc2 != myalloc)); AZ_TEST_ASSERT((myalloc2 != myalloc));

@ -49,7 +49,7 @@ namespace UnitTest
const char newName[] = "My new test allocator"; const char newName[] = "My new test allocator";
myalloc.set_name(newName); myalloc.set_name(newName);
EXPECT_EQ(0, strcmp(myalloc.get_name(), newName)); EXPECT_EQ(0, strcmp(myalloc.get_name(), newName));
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.get_max_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.max_size());
} }
} }
@ -61,10 +61,10 @@ namespace UnitTest
typename TestFixture::allocator_type::pointer_type data = myalloc.allocate(); typename TestFixture::allocator_type::pointer_type data = myalloc.allocate();
EXPECT_NE(nullptr, data); EXPECT_NE(nullptr, data);
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_allocated_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_allocated_size());
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (s_allocatorCapacity - 1), myalloc.get_max_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (s_allocatorCapacity - 1), myalloc.max_size() - myalloc.get_allocated_size());
myalloc.deallocate(data); myalloc.deallocate(data);
EXPECT_EQ(0, myalloc.get_allocated_size()); EXPECT_EQ(0, myalloc.get_allocated_size());
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.get_max_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * s_allocatorCapacity, myalloc.max_size());
} }
TYPED_TEST(ConcurrentAllocatorTestFixture, MultipleAllocateDeallocate) TYPED_TEST(ConcurrentAllocatorTestFixture, MultipleAllocateDeallocate)
@ -84,19 +84,19 @@ namespace UnitTest
EXPECT_EQ(dataSize, dataSet.size()); EXPECT_EQ(dataSize, dataSet.size());
dataSet.clear(); dataSet.clear();
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * dataSize, myalloc.get_allocated_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * dataSize, myalloc.get_allocated_size());
EXPECT_EQ((s_allocatorCapacity - dataSize) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size()); EXPECT_EQ((s_allocatorCapacity - dataSize) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size() - myalloc.get_allocated_size());
for (size_t i = 0; i < dataSize; i += 2) for (size_t i = 0; i < dataSize; i += 2)
{ {
myalloc.deallocate(data[i]); myalloc.deallocate(data[i]);
} }
EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (dataSize / 2), myalloc.get_allocated_size()); EXPECT_EQ(sizeof(typename TestFixture::allocator_type::value_type) * (dataSize / 2), myalloc.get_allocated_size());
EXPECT_EQ((s_allocatorCapacity - dataSize / 2) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size()); EXPECT_EQ((s_allocatorCapacity - dataSize / 2) * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size() - myalloc.get_allocated_size());
for (size_t i = 1; i < dataSize; i += 2) for (size_t i = 1; i < dataSize; i += 2)
{ {
myalloc.deallocate(data[i]); myalloc.deallocate(data[i]);
} }
EXPECT_EQ(0, myalloc.get_allocated_size()); EXPECT_EQ(0, myalloc.get_allocated_size());
EXPECT_EQ(s_allocatorCapacity * sizeof(typename TestFixture::allocator_type::value_type), myalloc.get_max_size()); EXPECT_EQ(s_allocatorCapacity * sizeof(typename TestFixture::allocator_type::value_type), myalloc.max_size());
} }
TYPED_TEST(ConcurrentAllocatorTestFixture, ConcurrentAllocateoDeallocate) TYPED_TEST(ConcurrentAllocatorTestFixture, ConcurrentAllocateoDeallocate)
@ -159,7 +159,7 @@ namespace UnitTest
EXPECT_NE(nullptr, aligned_data); EXPECT_NE(nullptr, aligned_data);
EXPECT_EQ(0, ((AZStd::size_t)aligned_data & (dataAlignment - 1))); EXPECT_EQ(0, ((AZStd::size_t)aligned_data & (dataAlignment - 1)));
EXPECT_EQ((s_allocatorCapacity - 1) * sizeof(aligned_int_type), myaligned_pool.get_max_size()); EXPECT_EQ((s_allocatorCapacity - 1) * sizeof(aligned_int_type), myaligned_pool.max_size() - myaligned_pool.get_allocated_size());
EXPECT_EQ(sizeof(aligned_int_type), myaligned_pool.get_allocated_size()); EXPECT_EQ(sizeof(aligned_int_type), myaligned_pool.get_allocated_size());
myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated. myaligned_pool.deallocate(aligned_data, sizeof(aligned_int_type), dataAlignment); // Make sure we free what we have allocated.

@ -1179,6 +1179,8 @@ namespace UnitTest
size_type Capacity() const override { return 1 * 1024 * 1024 * 1024; } size_type Capacity() const override { return 1 * 1024 * 1024 * 1024; }
/// Returns max allocation size if possible. If not returned value is 0 /// Returns max allocation size if possible. If not returned value is 0
size_type GetMaxAllocationSize() const override { return 1 * 1024 * 1024 * 1024; } size_type GetMaxAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
/// Returns max allocation size of a single contiguous allocation
size_type GetMaxContiguousAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
/// Returns a pointer to a sub-allocator or NULL. /// Returns a pointer to a sub-allocator or NULL.
IAllocatorAllocate* GetSubAllocator() override { return NULL; } IAllocatorAllocate* GetSubAllocator() override { return NULL; }
}; };

@ -39,7 +39,7 @@ namespace MCore
return 0; return 0;
} }
StaticAllocator::size_type StaticAllocator::get_max_size() const StaticAllocator::size_type StaticAllocator::max_size() const
{ {
return 0; return 0;
} }

@ -22,7 +22,7 @@ namespace MCore
StaticAllocator::size_type resize(pointer_type ptr, size_type newSize); StaticAllocator::size_type resize(pointer_type ptr, size_type newSize);
StaticAllocator::size_type get_max_size() const; StaticAllocator::size_type max_size() const;
StaticAllocator::size_type get_allocated_size() const; StaticAllocator::size_type get_allocated_size() const;
}; };

Loading…
Cancel
Save