summaryrefslogtreecommitdiff
path: root/Runtime/Allocator/TLSAllocator.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Allocator/TLSAllocator.cpp
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Allocator/TLSAllocator.cpp')
-rw-r--r--Runtime/Allocator/TLSAllocator.cpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/Runtime/Allocator/TLSAllocator.cpp b/Runtime/Allocator/TLSAllocator.cpp
new file mode 100644
index 0000000..00bf88b
--- /dev/null
+++ b/Runtime/Allocator/TLSAllocator.cpp
@@ -0,0 +1,198 @@
+#include "UnityPrefix.h"
+#include "TLSAllocator.h"
+#include "Runtime/Threads/Thread.h"
+#include "Runtime/Allocator/StackAllocator.h"
+
+#if ENABLE_MEMORY_MANAGER
+
+template <class UnderlyingAllocator>
+int TLSAllocator<UnderlyingAllocator>::s_NumberOfInstances = 0;
+
+template <class UnderlyingAllocator>
+UNITY_TLS_VALUE(UnderlyingAllocator*) TLSAllocator<UnderlyingAllocator>::m_UniqueThreadAllocator;
+
+template <class UnderlyingAllocator>
+TLSAllocator<UnderlyingAllocator>::TLSAllocator(const char* name)
+: BaseAllocator(name)
+{
+ if(s_NumberOfInstances != 0)
+ ErrorString("Only one instance of the TLS allocator is allowed because of TLS implementation");
+ s_NumberOfInstances++;
+ memset (m_ThreadTempAllocators, 0, sizeof(m_ThreadTempAllocators));
+}
+
+template <class UnderlyingAllocator>
+TLSAllocator<UnderlyingAllocator>::~TLSAllocator()
+{
+ s_NumberOfInstances--;
+}
+
+template <class UnderlyingAllocator>
+void TLSAllocator<UnderlyingAllocator>::ThreadInitialize(BaseAllocator *allocator)
+{
+ m_UniqueThreadAllocator = (UnderlyingAllocator*)allocator;
+
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] == NULL)
+ {
+ m_ThreadTempAllocators[i] = (UnderlyingAllocator*) allocator;
+ break;
+ }
+ }
+
+}
+
+template <class UnderlyingAllocator>
+void TLSAllocator<UnderlyingAllocator>::ThreadCleanup()
+{
+ UnderlyingAllocator* allocator = m_UniqueThreadAllocator;
+ m_UniqueThreadAllocator = NULL;
+
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] == allocator)
+ {
+ m_ThreadTempAllocators[i] = NULL;
+ break;
+ }
+ }
+ UNITY_DELETE(allocator, kMemManager);
+}
+
+template <class UnderlyingAllocator>
+void TLSAllocator<UnderlyingAllocator>::FrameMaintenance(bool cleanup)
+{
+ Assert(m_UniqueThreadAllocator->GetAllocatedMemorySize() == 0);
+}
+
+template <class UnderlyingAllocator>
+bool TLSAllocator<UnderlyingAllocator>::IsAssigned() const
+{
+ return m_UniqueThreadAllocator != NULL;
+}
+
+template <class UnderlyingAllocator>
+UnderlyingAllocator* TLSAllocator<UnderlyingAllocator>::GetCurrentAllocator()
+{
+ return m_UniqueThreadAllocator;
+}
+
+
+template <class UnderlyingAllocator>
+void* TLSAllocator<UnderlyingAllocator>::Allocate( size_t size, int align )
+{
+ UnderlyingAllocator* alloc = GetCurrentAllocator();
+ return alloc ? alloc->UnderlyingAllocator::Allocate(size, align) : NULL;
+}
+
+template <class UnderlyingAllocator>
+void* TLSAllocator<UnderlyingAllocator>::Reallocate( void* p, size_t size, int align )
+{
+ UnderlyingAllocator* alloc = GetCurrentAllocator();
+ if(!alloc)
+ return NULL;
+ if(alloc->UnderlyingAllocator::Contains(p))
+ return alloc->UnderlyingAllocator::Reallocate(p, size, align);
+
+ return NULL;
+}
+
+template <class UnderlyingAllocator>
+void TLSAllocator<UnderlyingAllocator>::Deallocate( void* p )
+{
+ UnderlyingAllocator* alloc = GetCurrentAllocator();
+ DebugAssert(alloc);
+ DebugAssert(alloc->UnderlyingAllocator::Contains(p));
+ return alloc->UnderlyingAllocator::Deallocate(p);
+}
+
+template <class UnderlyingAllocator>
+bool TLSAllocator<UnderlyingAllocator>::TryDeallocate( void* p )
+{
+ UnderlyingAllocator* alloc = GetCurrentAllocator();
+ if(!alloc)
+ return false;
+
+ if(!alloc->UnderlyingAllocator::Contains(p))
+ return false;
+
+ alloc->UnderlyingAllocator::Deallocate(p);
+ return true;
+}
+
+
+template <class UnderlyingAllocator>
+bool TLSAllocator<UnderlyingAllocator>::Contains( const void* p )
+{
+ UnderlyingAllocator* alloc = GetCurrentAllocator();
+ if(alloc && alloc->UnderlyingAllocator::Contains(p))
+ return true;
+ return false;
+}
+
+template <class UnderlyingAllocator>
+size_t TLSAllocator<UnderlyingAllocator>::GetAllocatedMemorySize( ) const
+{
+ size_t allocated = 0;
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] != NULL)
+ allocated += m_ThreadTempAllocators[i]->UnderlyingAllocator::GetAllocatedMemorySize();
+ }
+ return allocated;
+}
+
+template <class UnderlyingAllocator>
+size_t TLSAllocator<UnderlyingAllocator>::GetAllocatorSizeTotalUsed() const
+{
+ size_t total = 0;
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] != NULL)
+ total += m_ThreadTempAllocators[i]->UnderlyingAllocator::GetAllocatorSizeTotalUsed();
+ }
+ return total;
+}
+
+template <class UnderlyingAllocator>
+size_t TLSAllocator<UnderlyingAllocator>::GetReservedSizeTotal() const
+{
+ size_t total = 0;
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] != NULL)
+ total += m_ThreadTempAllocators[i]->UnderlyingAllocator::GetReservedSizeTotal();
+ }
+ return total;
+}
+
+template <class UnderlyingAllocator>
+size_t TLSAllocator<UnderlyingAllocator>::GetPtrSize( const void* ptr ) const
+{
+ // all allocators have the same allocation header
+ return m_ThreadTempAllocators[0]->UnderlyingAllocator::GetPtrSize(ptr);
+}
+
+template <class UnderlyingAllocator>
+ProfilerAllocationHeader* TLSAllocator<UnderlyingAllocator>::GetProfilerHeader( const void* ptr ) const
+{
+ return m_ThreadTempAllocators[0]->UnderlyingAllocator::GetProfilerHeader(ptr);
+}
+
+
+template <class UnderlyingAllocator>
+bool TLSAllocator<UnderlyingAllocator>::CheckIntegrity()
+{
+ bool succes = true;
+ for(int i = 0; i < kMaxThreadTempAllocators; i++)
+ {
+ if(m_ThreadTempAllocators[i] != NULL)
+ succes &= m_ThreadTempAllocators[i]->UnderlyingAllocator::CheckIntegrity();
+ }
+ return succes;
+}
+
+template class TLSAllocator< StackAllocator >;
+
+#endif // #if ENABLE_MEMORY_MANAGER