diff --git a/Allocators/CMakeLists.txt b/Allocators/CMakeLists.txt deleted file mode 100644 index 8b59432..0000000 --- a/Allocators/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -project(Allocators) - -### ---------------------- Static Library --------------------- ### -file(GLOB SOURCES "./private/*.cpp") -file(GLOB HEADERS "./public/*.hpp") -add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) -target_include_directories(${PROJECT_NAME} PUBLIC ./public/) -target_link_libraries(${PROJECT_NAME} PUBLIC Callstack) - -### -------------------------- Tests -------------------------- ### -enable_testing() -file(GLOB TEST_SOURCES "./tests/*.cpp") -add_executable(Tests${PROJECT_NAME} ${TEST_SOURCES}) -target_link_libraries(Tests${PROJECT_NAME} ${PROJECT_NAME} UnitTest++) -add_test(NAME Tests${PROJECT_NAME} COMMAND Tests${PROJECT_NAME}) \ No newline at end of file diff --git a/Allocators/README.md b/Allocators/README.md deleted file mode 100644 index d2beeba..0000000 --- a/Allocators/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Profiling - -## Memory Leaks - -Example program with memory leaks: - -```c++ -#include "allocators.h" - -void test_call22() { new int; } -void test_call21() { new float; } - -void test_call11() { - test_call21(); - test_call22(); -} - -int main(char argc, char* argv[]) { - tp::ModuleManifest* ModuleDependencies[] = { &tp::gModuleAllocators, NULL }; - tp::ModuleManifest TestModule("Test", NULL, NULL, ModuleDependencies); - TestModule.initialize(); - - test_call11(); - - TestModule.deinitialize(); -} - -``` -If memory leaks were detected it will be logged in the output console. - -![image](https://user-images.githubusercontent.com/63184036/222794298-3f238de4-c0b8-41fa-b7ec-c0c675da8f05.png) - -Also debug.memleaks binary will be generated in the working directory that can be viewed with MemLeaks Viewer. - -![image](https://user-images.githubusercontent.com/63184036/222793169-a405effe-72be-42fc-b375-bb06dce0a735.png) - diff --git a/Allocators/private/Allocators.cpp b/Allocators/private/Allocators.cpp deleted file mode 100644 index 1b87345..0000000 --- a/Allocators/private/Allocators.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -#include "Allocators.hpp" -#include "HeapAllocatorGlobal.hpp" - -#include -#include - -static bool init(const tp::ModuleManifest* self) { - tp::HeapAllocGlobal::stopIgnore(); - if (tp::HeapAllocGlobal::getNAllocations()) { - printf("Warning : Operator new was called outside module initialization!!\n\n"); - } - return true; -} - -static void deinit(const tp::ModuleManifest* self) { - tp::HeapAllocGlobal::checkLeaks(); -} - -static tp::ModuleManifest* sModuleDependencies[] = { nullptr }; -tp::ModuleManifest tp::gModuleAllocators = ModuleManifest("Allocators", init, deinit, sModuleDependencies); - -void* operator new(size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); } -void* operator new[](size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); } -void operator delete(void* aPtr) noexcept { tp::HeapAllocGlobal::deallocate(aPtr); } -void operator delete[](void* aPtr) noexcept { tp::HeapAllocGlobal::deallocate(aPtr); } - -void* operator new(size_t aSize, tp::HeapAlloc& aAlloc) { return aAlloc.allocate(aSize); } -void* operator new[](size_t aSize, tp::HeapAlloc& aAlloc) { return aAlloc.allocate(aSize); } -void operator delete(void* aPtr, tp::HeapAlloc& aAlloc) { aAlloc.deallocate(aPtr); } -void operator delete[](void* aPtr, tp::HeapAlloc& aAlloc) { aAlloc.deallocate(aPtr); } - -void* operator new(size_t aSize, tp::HeapAllocGlobal& aAlloc) { return tp::HeapAllocGlobal::allocate(aSize); } -void* operator new[](size_t aSize, tp::HeapAllocGlobal& aAlloc) { return tp::HeapAllocGlobal::allocate(aSize); } -void operator delete(void* aPtr, tp::HeapAllocGlobal& aAlloc) { tp::HeapAllocGlobal::deallocate(aPtr); } -void operator delete[](void* aPtr, tp::HeapAllocGlobal& aAlloc) { tp::HeapAllocGlobal::deallocate(aPtr); } \ No newline at end of file diff --git a/Allocators/private/HeapAllocator.cpp b/Allocators/private/HeapAllocator.cpp deleted file mode 100644 index b6f76bc..0000000 --- a/Allocators/private/HeapAllocator.cpp +++ /dev/null @@ -1,76 +0,0 @@ - - -#include "HeapAllocator.hpp" -#include "HeapAllocatorGlobal.hpp" - -#include "PrivateConfig.hpp" - -#include - -using namespace tp; - -#if not defined(MEM_DEBUG) - -// ----------------------- Release Implementation ---------------------------- // -void* HeapAlloc::allocate(ualni aBlockSize) { return malloc(aBlockSize); } -void HeapAlloc::deallocate(void* aPtr) { - if (!aPtr) return; - free(aPtr); -} -HeapAlloc::~HeapAlloc() {} - -#else - -namespace tp { - struct MemHeadLocal { - MemHeadLocal* mPrev; - MemHeadLocal* mNext; - }; -} - -void* HeapAlloc::allocate(ualni aBlockSize) { - auto head = (MemHeadLocal*) HeapAllocGlobal::allocate(aBlockSize + sizeof(MemHeadLocal)); - auto out = head + 1; - - mNumAllocations++; - if (mEntry) { - DEBUG_ASSERT(!mEntry->mNext) - head->mNext = nullptr; - head->mPrev = mEntry; - mEntry->mNext = head; - } else { - head->mNext = nullptr; - head->mPrev = nullptr; - } - mEntry = head; - - return out; -} - -void HeapAlloc::deallocate(void* aPtr) { - if (!aPtr) return; - - auto head = ((MemHeadLocal*) (aPtr)) - 1; - - mNumAllocations--; - DEBUG_ASSERT(!mEntry->mNext) - if (head->mNext) head->mNext->mPrev = head->mPrev; - if (head->mPrev) head->mPrev->mNext = head->mNext; - if (head == mEntry) { - mEntry = head->mPrev; - } - - HeapAllocGlobal::deallocate(head); -} - -HeapAlloc::~HeapAlloc() { - if (mNumAllocations) { - DEBUG_ASSERT(0 && "Destruction of not freed Allocator") - -#ifdef MEM_STACK_TRACE - // TODO : log leaks and free them up -#endif - } -} - -#endif diff --git a/Allocators/private/HeapAllocatorGlobal.cpp b/Allocators/private/HeapAllocatorGlobal.cpp deleted file mode 100644 index 8f6450e..0000000 --- a/Allocators/private/HeapAllocatorGlobal.cpp +++ /dev/null @@ -1,232 +0,0 @@ - - -#include "HeapAllocatorGlobal.hpp" -#include "PrivateConfig.hpp" - -#include "Callstack.hpp" -#include "Utils.hpp" - -#include -#include - -using namespace tp; - -#if not defined(MEM_DEBUG) - -// ----------------------- Release Implementation ---------------------------- // - -void* HeapAllocGlobal::allocate(ualni aBlockSize) { return malloc(aBlockSize); } -void HeapAllocGlobal::deallocate(void* aPtr) { - if (!aPtr) return; - free(aPtr); -} -HeapAllocGlobal::~HeapAllocGlobal() = default; -bool HeapAllocGlobal::checkLeaks() { return false; } -void HeapAllocGlobal::startIgnore() {} -void HeapAllocGlobal::stopIgnore() {} -ualni HeapAllocGlobal::getNAllocations() { return 0; } - -#else - -tp::MemHead* tp::HeapAllocGlobal::mEntry = nullptr; -tp::ualni tp::HeapAllocGlobal::mNumAllocations = 0; -std::mutex tp::HeapAllocGlobal::mMutex; -bool tp::HeapAllocGlobal::mIgnore = true; -bool tp::HeapAllocGlobal::mEnableCallstack = true; - -#ifdef MEM_STACK_TRACE -tp::CallStackCapture tp::HeapAllocGlobal::mCallstack; -#endif - - // ----------------------- Debug Implementation ---------------------------- // -// |----------------| -// | MemHead | -// |----------------| -// | wrap top | -// |----------------| - Allocated Block Layout -// | data | -// |----------------| -// | wrap bottom | -// |----------------| - -namespace tp { - struct MemHead { - MemHead* mPrev; - MemHead* mNext; - uhalni mBlockSize; - uhalni mIgnored; -#ifdef MEM_STACK_TRACE - const CallStackCapture::CallStack* mCallStack; -#else - void* p; -#endif - }; -} - -enum : ualni { - ALIGNED_SIZE = ENV_ALNI_SIZE_B, - WRAP_SIZE = MEM_WRAP_SIZE * ALIGNED_SIZE, - WRAP_VAL = MEM_WRAP_FILL_VAL, - HEAD_SIZE = sizeof(MemHead), - CLEAR_ALLOC_VAL = MEM_CLEAR_ON_ALLOC_VAL, - CLEAR_DEALLOC_VAL = MEM_CLEAR_ON_DEALLOC_VAL, -}; - -void* HeapAllocGlobal::allocate(ualni aBlockSize) { - - static_assert(HEAD_SIZE % ALIGNED_SIZE == 0, "Heap Allocator Configuration Error"); - - if (aBlockSize % ALIGNED_SIZE) { - aBlockSize = (aBlockSize / ALIGNED_SIZE + 1) * ALIGNED_SIZE; - } - -// 1) Allocate the block -ALLOCATE: - auto head = (MemHead*) malloc(aBlockSize + WRAP_SIZE * 2 + HEAD_SIZE); - if (!head) { - printf("WARNING : Cant allocate memory. Trying again\n"); - goto ALLOCATE; // Just freeze if no memory is available - } - - auto wrap_top = (int1*) (head + 1); - auto data = wrap_top + WRAP_SIZE; - auto wrap_bottom = data + aBlockSize; - - head->mBlockSize = aBlockSize; - head->mIgnored = mIgnore; - - // 2) Link with existing blocks - mMutex.lock(); - mNumAllocations++; - if (mEntry) { - DEBUG_ASSERT(mEntry->mNext == nullptr) - head->mNext = nullptr; - head->mPrev = mEntry; - mEntry->mNext = head; - } else { - head->mNext = nullptr; - head->mPrev = nullptr; - } - mEntry = head; - - // 3) Trace the stack -#ifdef MEM_STACK_TRACE - // check if somewhat decides to call new within static variable initialization - head->mCallStack = (mEnableCallstack && mCallstack.initialized) ? mCallstack.getSnapshot() : nullptr; -#endif - - mMutex.unlock(); - - // 4) Wrap fill - memSetVal(wrap_top, WRAP_SIZE, WRAP_VAL); - memSetVal(wrap_bottom, WRAP_SIZE, WRAP_VAL); - - // 5) clear data -#ifdef MEM_CLEAR_ON_ALLOC - memSetVal(data, aBlockSize, CLEAR_ALLOC_VAL); -#endif - - return data; -} - -void HeapAllocGlobal::deallocate(void* aPtr) { - if (!aPtr) return; - - // 1) Restore the pointers - auto head = ((MemHead*) ((int1*) aPtr - WRAP_SIZE)) - 1; - auto wrap_top = (int1*) (head + 1); - auto data = wrap_top + WRAP_SIZE; - auto wrap_bottom = data + head->mBlockSize; - - // 2) Unlink with blocks - mMutex.lock(); - mNumAllocations--; - DEBUG_ASSERT(!mEntry->mNext) - if (head->mNext) head->mNext->mPrev = head->mPrev; - if (head->mPrev) head->mPrev->mNext = head->mNext; - if (head == mEntry) { - mEntry = head->mPrev; - } - - if (!head->mIgnored) { - // 3) Check the wrap - if (memCompareVal(wrap_top, WRAP_SIZE, WRAP_VAL)) { -#ifdef MEM_STACK_TRACE - if (head->mCallStack) mCallstack.printSnapshot(head->mCallStack); -#endif - ASSERT(!"Allocated Block Wrap Corrupted!") - } - - if (memCompareVal(wrap_bottom, WRAP_SIZE, WRAP_VAL)) { -#ifdef MEM_STACK_TRACE - if (head->mCallStack) mCallstack.printSnapshot(head->mCallStack); -#endif - ASSERT(!"Allocated Block Wrap Corrupted!") - } - - // 4) clear data -#ifdef MEM_CLEAR_ON_ALLOC - memSetVal(data, head->mBlockSize, CLEAR_DEALLOC_VAL); -#endif - } - - mMutex.unlock(); - - // 5) free the block - free(head); -} - -bool HeapAllocGlobal::checkLeaks() { - ualni ignoredCount = 0; - for (auto iter = mEntry; iter; iter = iter->mPrev) { - ignoredCount += iter->mIgnored; - } - - // 1) Check for not deallocated memory - if (mNumAllocations && ignoredCount < mNumAllocations) { - -#ifdef MEM_STACK_TRACE - for (auto iter = mEntry; iter; iter = iter->mPrev) { - if (!iter->mIgnored && iter->mCallStack) mCallstack.printSnapshot(iter->mCallStack); - } -#endif - - printf(" Count : %llu", mNumAllocations - ignoredCount); - - ASSERT(!"Destruction of not freed Allocator") - return true; - } - return false; -} - -void HeapAllocGlobal::startIgnore() { - mMutex.lock(); - mIgnore = true; - mMutex.unlock(); -} - -void HeapAllocGlobal::stopIgnore() { - mMutex.lock(); - mIgnore = false; - mMutex.unlock(); -} - -ualni HeapAllocGlobal::getNAllocations() { - return mNumAllocations; -} - -void HeapAllocGlobal::enableCallstack() { - mMutex.lock(); - mEnableCallstack = true; - mMutex.unlock(); -} - -void HeapAllocGlobal::disableCallstack() { - mMutex.lock(); - mEnableCallstack = false; - mMutex.unlock(); -} - -HeapAllocGlobal::~HeapAllocGlobal() = default; - -#endif diff --git a/Allocators/public/Allocators.hpp b/Allocators/public/Allocators.hpp deleted file mode 100644 index ad29c25..0000000 --- a/Allocators/public/Allocators.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "Utils.hpp" - -#include "ChunkAllocator.hpp" -#include "HeapAllocator.hpp" -#include "HeapAllocatorGlobal.hpp" -#include "PoolAllocator.hpp" - -namespace tp { - extern ModuleManifest gModuleAllocators; -} - -void* operator new(std::size_t aSize); -void* operator new[](std::size_t aSize); -void operator delete(void* aPtr) noexcept; -void operator delete[](void* aPtr) noexcept; - -void* operator new(std::size_t aSize, tp::HeapAlloc& aAlloc); -void* operator new[](std::size_t aSize, tp::HeapAlloc& aAlloc); -void operator delete(void* aPtr, tp::HeapAlloc& aAlloc); -void operator delete[](void* aPtr, tp::HeapAlloc& aAlloc); - -void* operator new(std::size_t aSize, tp::HeapAllocGlobal& aAlloc); -void* operator new[](std::size_t aSize, tp::HeapAllocGlobal& aAlloc); -void operator delete(void* aPtr, tp::HeapAllocGlobal& aAlloc); -void operator delete[](void* aPtr, tp::HeapAllocGlobal& aAlloc); \ No newline at end of file diff --git a/Allocators/public/ChunkAllocator.hpp b/Allocators/public/ChunkAllocator.hpp deleted file mode 100644 index 42f84e6..0000000 --- a/Allocators/public/ChunkAllocator.hpp +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once - -/* -* Implementation uses embedded one-directional linked list to track free blocks. -* The embedded part ensures that there is no memory overhead on block specifically. -* Linked list is initialized iteratively on each allocation if it has not been already. - -* Allocating: -* 1) updating list entry to stored in the entry itself next free pointer -* 2) returning entry before (1). -* -* Deallocating: -* 1) assigning list entry value to the deleted block -* 2) updating list entry to that block. -*/ - -#include "Environment.hpp" -#include "HeapAllocatorGlobal.hpp" -#include "PrivateConfig.hpp" - -namespace tp { - - // Chunk Allocator - // Constant time allocations and de-allocations in any order. - // Memory blocks are fixed in size and number of blocks can not exceed given parameter. - template - class ChunkAlloc { - - enum : ualni { - ALIGNED_SIZE = ENV_ALNI_SIZE_B, - - WRAP_SIZE_ALN = MEM_WRAP_SIZE / 2, - WRAP_SIZE = WRAP_SIZE_ALN * ALIGNED_SIZE, - - WRAP_VAL = MEM_WRAP_FILL_VAL, - CLEAR_ALLOC_VAL = MEM_CLEAR_ON_ALLOC_VAL, - CLEAR_DEALLOC_VAL = MEM_CLEAR_ON_DEALLOC_VAL, - }; - - static constexpr ualni dataSize() { - auto BLOCK_SIZE_BYTES = sizeof(tType); - auto BLOCK_SIZE_ALIGNED = BLOCK_SIZE_BYTES / ALIGNED_SIZE; - return BLOCK_SIZE_ALIGNED; - } - - static constexpr ualni blockSize() { - auto BLOCK_SIZE_BYTES = sizeof(tType); - auto BLOCK_SIZE = dataSize() + bool(BLOCK_SIZE_BYTES % ALIGNED_SIZE) + WRAP_SIZE_ALN * 2; - return BLOCK_SIZE; - } - - private: - ualni* mNextBlock; - ualni mNumFreeBlocks; - ualni mNumInitBlocks; - ualni mBuff[tNumBlocks * blockSize() * ALIGNED_SIZE]; - - public: - ChunkAlloc() { - mNumFreeBlocks = tNumBlocks; - mNumInitBlocks = 0; - mNextBlock = mBuff; - } - - ~ChunkAlloc() = default; // TODO : check for leaks - - public: - void* allocate(ualni) { - DEBUG_ASSERT(mNumFreeBlocks && "Out Of Memory") - - // 1) PreInitialize blocks - if (mNumInitBlocks < tNumBlocks) { - mBuff[mNumInitBlocks * blockSize()] = (ualni) (mBuff + (mNumInitBlocks + 1) * blockSize()); - mNumInitBlocks++; - } - - // 2) Find free block and update next free block - auto data = mNextBlock; - mNextBlock = (ualni*) (*data); - mNumFreeBlocks--; - -#ifdef MEM_DEBUG - // 3) Fill Wrap and offset data - auto wrap_top = data; - auto wrap_bottom = data + WRAP_SIZE_ALN + dataSize(); - - memSetVal(wrap_top, WRAP_SIZE, WRAP_VAL); - memSetVal(wrap_bottom, WRAP_SIZE, WRAP_VAL); - -// 4) Clear data -#ifdef MEM_CLEAR_ON_ALLOC - memSetVal(data + WRAP_SIZE_ALN, dataSize() * ALIGNED_SIZE, CLEAR_ALLOC_VAL); -#endif - - data += WRAP_SIZE_ALN; -#endif - - return data; - } - - void deallocate(void* aPtr) { - DEBUG_ASSERT(aPtr >= mBuff && aPtr < mBuff + tNumBlocks * blockSize()) - - auto block = (ualni*) aPtr; - -#ifdef MEM_DEBUG - // 3) Check Wrap and offset data - auto wrap_bottom = block + dataSize(); - auto wrap_top = block - WRAP_SIZE_ALN; - block = wrap_top; - - // 3) Check the wrap - ASSERT(!memCompareVal(wrap_top, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!") - ASSERT(!memCompareVal(wrap_bottom, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!") - -// 4) Clear data -#ifdef MEM_CLEAR_ON_ALLOC - memSetVal(block, blockSize() * ALIGNED_SIZE, CLEAR_DEALLOC_VAL); -#endif - -#endif - - (*block) = (ualni) mNextBlock; - mNextBlock = block; - mNumFreeBlocks++; - } - - [[nodiscard]] bool checkWrap() const { return false; } - void checkValid() {} - - public: - [[nodiscard]] bool isFull() const { return !mNumFreeBlocks; } - [[nodiscard]] bool isEmpty() const { return mNumFreeBlocks == tNumBlocks; } - [[nodiscard]] const ualni* getBuff() const { return mBuff; } - }; -} \ No newline at end of file diff --git a/Allocators/public/HeapAllocator.hpp b/Allocators/public/HeapAllocator.hpp deleted file mode 100644 index 59aedba..0000000 --- a/Allocators/public/HeapAllocator.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Environment.hpp" - -namespace tp { - - class HeapAlloc { - -#ifdef MEM_DEBUG - ualni mNumAllocations = 0; - struct MemHeadLocal* mEntry = nullptr; -#endif - - public: - HeapAlloc() = default; - ~HeapAlloc(); - - public: - void* allocate(ualni aBlockSize); - void deallocate(void* aPtr); - - public: - [[nodiscard]] bool checkWrap() const { return false; } - void checkValid() {} - }; -} diff --git a/Allocators/public/HeapAllocatorGlobal.hpp b/Allocators/public/HeapAllocatorGlobal.hpp deleted file mode 100644 index 8c8b892..0000000 --- a/Allocators/public/HeapAllocatorGlobal.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "Callstack.hpp" -#include - -namespace tp { - - class HeapAllocGlobal { - -#ifdef MEM_DEBUG - static ualni mNumAllocations; - static struct MemHead* mEntry; - static std::mutex mMutex; - static bool mIgnore; - static bool mEnableCallstack; -#ifdef MEM_STACK_TRACE // Save stack on allocation call - static CallStackCapture mCallstack; -#endif -#endif - - public: - HeapAllocGlobal() = default; - ~HeapAllocGlobal(); - - public: - static void* allocate(ualni aBlockSize); - static void deallocate(void* aPtr); - - static bool checkLeaks(); - static void startIgnore(); - static void stopIgnore(); - static ualni getNAllocations(); - - static void enableCallstack(); - static void disableCallstack(); - - public: - [[nodiscard]] bool checkWrap() const { return false; } - void checkValid() {} - }; -} diff --git a/Allocators/public/NewPlacement.hpp b/Allocators/public/NewPlacement.hpp deleted file mode 100644 index 7641add..0000000 --- a/Allocators/public/NewPlacement.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "Common.hpp" - -#ifndef ENV_OS_WINDOWS -inline void* operator new(std::size_t aSize, void* aWhere) noexcept { return aWhere; } -inline void* operator new[](std::size_t aSize, void* aWhere) noexcept { return aWhere; } -#endif diff --git a/Allocators/public/PoolAllocator.hpp b/Allocators/public/PoolAllocator.hpp deleted file mode 100644 index 3fbe5d9..0000000 --- a/Allocators/public/PoolAllocator.hpp +++ /dev/null @@ -1,161 +0,0 @@ -#pragma once - -/* -Implementation: -* Adding chunk pointer to each chunk to form one-directional list that keeps track of free chunk -* Storing ordered pointers to chunks in order to find desired chunk from delete pointer on de-allocation in log time -* -* Allocations: -* 1) allocate with chunk stored in list entry -* 2) ... -* -* De-allocations: -* 1) binary-search with delete pointer to find desired chunk -* 2) ... -* -*/ - -#include "ChunkAllocator.hpp" - -namespace tp { - - // Pool Allocator - // Overcomes chunk allocator fixed number of max allocations - template - class PoolAlloc { - - typedef ChunkAlloc Chunk; - - struct Chunks { - - void add(Chunk* aChunk) { - - if (!mBuff) { - mLen = 16; - mBuff = (Chunk**) HeapAllocGlobal::allocate(sizeof(Chunk*) * mLen); - mUsedLen = 1; - mBuff[0] = aChunk; - return; - } - - // ensure order - auto smaller_address = findUtil(mBuff, mBuff + mUsedLen, aChunk); - for (auto iter = mBuff + mUsedLen; iter != smaller_address; iter--) { - *iter = *(iter - 1); - } - - *(smaller_address) = aChunk; - mUsedLen++; - - // check for buff overflow - if (mUsedLen == mLen) { - auto prevBuff = mBuff; - mBuff = (Chunk**) HeapAllocGlobal::allocate(sizeof(Chunk*) * mLen * 2); - memCopy(mBuff, prevBuff, sizeof(Chunk*) * mUsedLen); - mLen *= 2; - HeapAllocGlobal::deallocate(prevBuff); - } - } - - void remove(Chunk** del_address) { - if (mUsedLen == 1) { - mLen = 0; - mUsedLen = 0; - HeapAllocGlobal::deallocate(mBuff); - mBuff = nullptr; - return; - } - - // ensure order - for (auto iter = del_address; iter != mBuff + mUsedLen - 1; iter++) { - *iter = *(iter + 1); - } - - mUsedLen--; - - // check for buff low usage - if ((halnf) mUsedLen / (halnf) mLen < 0.25f) { - auto prevBuff = mBuff; - mBuff = (Chunk**) HeapAllocGlobal::allocate(sizeof(Chunk*) * mLen / 2); - memCopy(mBuff, prevBuff, sizeof(Chunk*) * mUsedLen); - mLen /= 2; - HeapAllocGlobal::deallocate(prevBuff); - } - } - - [[nodiscard]] Chunk** find(void* aPtr) { return findUtil(mBuff, mBuff + mUsedLen, aPtr) - 1; } - - [[nodiscard]] Chunk* findNotFull() const { - for (ualni idx = 0; idx < mUsedLen; idx++) { - if (!mBuff[idx]->isFull()) { - return mBuff[idx]; - } - } - return nullptr; - } - - Chunk** mBuff = nullptr; - ualni mUsedLen = 0; - ualni mLen = 0; - - private: - Chunk** findUtil(Chunk** aLeft, Chunk** aRight, void* aPtr) { - auto range = ualni(aRight - aLeft); - if (range == 1) { - return (aPtr < *aLeft) ? aLeft : aRight; - } - auto middle = aLeft + range / 2; - return (aPtr >= (*middle)) ? findUtil(middle, aRight, aPtr) : findUtil(aLeft, middle, aPtr); - } - }; - - private: - Chunks mChunks; - Chunk* mFreeChunk = nullptr; - - public: - PoolAlloc() = default; - ~PoolAlloc() = default; - - public: - void* allocate(ualni) { - if (!mFreeChunk || mFreeChunk->isFull()) { - auto new_free_chunk = mChunks.findNotFull(); - if (!new_free_chunk) { - new_free_chunk = new (HeapAllocGlobal::allocate(sizeof(Chunk))) Chunk(); - DEBUG_ASSERT(new_free_chunk) - mChunks.add(new_free_chunk); - } - mFreeChunk = new_free_chunk; - } - return mFreeChunk->allocate(0); - } - - void deallocate(void* aPtr) { - if (!aPtr) return; - auto chunk = mChunks.find(aPtr); - (*chunk)->deallocate(aPtr); - if ((*chunk)->isEmpty()) { - if (mFreeChunk == *chunk) mFreeChunk = nullptr; - HeapAllocGlobal::deallocate(*chunk); - mChunks.remove(chunk); - } - } - - public: - [[nodiscard]] bool checkWrap() const { return false; } - - void checkValid() { - return; - for (auto i = 0; i < mChunks.mUsedLen; i++) { - for (auto j = 0; j < mChunks.mUsedLen; j++) { - if (i > j) { - ASSERT(mChunks.mBuff[i] > mChunks.mBuff[j]) - } else if (i < j) { - ASSERT(mChunks.mBuff[i] < mChunks.mBuff[j]) - } - } - } - } - }; -} diff --git a/Allocators/public/PrivateConfig.hpp b/Allocators/public/PrivateConfig.hpp deleted file mode 100644 index e8d735e..0000000 --- a/Allocators/public/PrivateConfig.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#define MEM_WRAP_SIZE 8 // Wrapping Size in aligned units -#define MEM_WRAP_FILL_VAL 0xBB // Wrapping Fill Value -#define MEM_CLEAR_ON_ALLOC // Clear data on allocation -#define MEM_CLEAR_ON_DEALLOC // Clear data on free -#define MEM_CLEAR_ON_DEALLOC_VAL 0xAA // Clear data on free -#define MEM_CLEAR_ON_ALLOC_VAL 0xCC // Clear data on free -#define MEM_STACK_TRACE_MAX_DEPTH 32 // Call stack max depth \ No newline at end of file diff --git a/Allocators/tests/Test.cpp b/Allocators/tests/Test.cpp deleted file mode 100644 index 4b0563d..0000000 --- a/Allocators/tests/Test.cpp +++ /dev/null @@ -1,249 +0,0 @@ - -#include "UnitTest++/UnitTest++.h" - -#include "Allocators.hpp" -#include "Utils.hpp" - -#include - -using namespace tp; - -struct TestStruct { - alni val = 0; - - TestStruct() : - val(0) {} - explicit TestStruct(alni val) : - val(val) {} - TestStruct(const TestStruct& in) : - val(in.val) {} - - ~TestStruct() { val = -1; } - - bool operator==(const TestStruct& in) const { return in.val == val; } -}; - -template -class TestBenches { - - tAllocator mAlloc{}; - TestStruct mData[tSize]{}; - TestStruct* mLoaded[tSize]{}; - bool mIsLoaded[tSize]{}; - alni mLoadedNum = 0; - -public: - TestBenches() { - for (alni i = 0; i < tSize; i++) { - mData[i].val = i; - mIsLoaded[i] = false; - mLoaded[i] = nullptr; - } - } - - void runTests() { - try { - test1(); - test2(); - test3(); - test4(); - test5(); - test6(); - } catch (...) { - ASSERT(false) - } - } - -private: - alni randomIdx(bool state, Range range = { 0, tSize }) { - RAND: - auto idx = alni(alnf(range.idxBegin()) + randomFloat() * alnf(range.idxDiff() + 1)); - idx = clamp(idx, alni(0), tSize - 1); - if (state == mIsLoaded[idx]) goto RAND; - return idx; - } - - void verifyIntegrity() { - mAlloc.checkValid(); - ASSERT(!mAlloc.checkWrap()) - for (alni i = 0; i < tSize; i++) { - if (mIsLoaded[i]) { - ASSERT(*mLoaded[i] == mData[i]) - } - } - } - - void loadItem(alni idx) { - if (mIsLoaded[idx]) return; - verifyIntegrity(); - mLoaded[idx] = new (mAlloc.allocate(sizeof(TestStruct))) TestStruct(mData[idx]); - ASSERT(mLoaded[idx]); - mIsLoaded[idx] = true; - mLoadedNum++; - verifyIntegrity(); - } - - void unloadItem(alni idx) { - if (!mIsLoaded[idx]) return; - verifyIntegrity(); - mLoaded[idx]->~TestStruct(); - mAlloc.deallocate(mLoaded[idx]); - mIsLoaded[idx] = false; - mLoadedNum--; - verifyIntegrity(); - } - - void changeStates(Range rg, bool load, bool reversed = false, bool random = false) { - for (auto i : rg) { - alni idx = i; - if (random) { - idx = randomIdx(load, rg); - } else if (reversed) { - idx = rg.idxEnd() - i - 1; - } - (load) ? loadItem(idx) : unloadItem(idx); - } - } - - // full down-up load then up-down unload - void test1() { - changeStates({ 0, tSize }, true); - changeStates({ 0, tSize }, false, true); - } - - // full down-up load then down-up unload - void test2() { - changeStates({ 0, tSize }, true); - changeStates({ 0, tSize }, false); - } - - // full random load then random unload - void test3() { - changeStates({ 0, tSize }, true, false, true); - changeStates({ 0, tSize }, false, false, true); - } - - // combo tests 1-3 - void test4() { - test1(); - test1(); - - test2(); - test2(); - - test3(); - test3(); - } - - static alnf sineUpFunction(alnf aSize, alnf aX, bool aReverse) { - alnf end = 4 * 3.14159; - alnf a = (2 / 7.f) * aSize; - alnf b = end / aSize; - - alni c = ((-1 * aReverse) + (1 * !aReverse)); - alnf c1 = (aX - (end * aReverse)) / b; - alnf c2 = (a * sin(aX - (end * aReverse))); - alnf out = c1 + c2; - return (alnf) c * out; - } - - // sin load & sin unload with ~1/2 drop factor - void test5() { - alnf end = 4 * 3.14159; - alnf step = end / 4.f; - - for (char i = 0; i < 2; i++) { - for (alnf x = 0; x <= end; x += step) { - - alni target_alloc_count = (alni) ceil(sineUpFunction(tSize, x, i)); - target_alloc_count = clamp(target_alloc_count, alni(0), tSize); - - while (mLoadedNum > target_alloc_count) { - unloadItem(randomIdx(0)); - } - while (mLoadedNum < target_alloc_count) { - loadItem(randomIdx(1)); - } - } - } - } - - void checkWrap(ualni offset, bool after) { - offset = clamp(offset, (ualni) 1, (ualni) MEM_WRAP_SIZE); - - TestStruct* ts = mLoaded[randomIdx(0)]; - ualni shift = (sizeof(TestStruct) * after) + (offset - 1) * after - offset * (!after); - uint1* address = (((uint1*) ts) + shift); - - uint1 val = *address; - *address = 5; - - ASSERT(!mAlloc.checkWrap()); - - *address = val; - } - - // mem guards test - void test6() { - changeStates({ 0, tSize }, 1); -#ifdef MEM_DEBUG - for (alni after = 0; after < 2; after++) { - for (alni offset = 1; offset <= MEM_WRAP_SIZE; offset++) { - checkWrap(offset, after); - } - } -#endif - changeStates({ 0, tSize }, 0); - } -}; - -const ualni size = 500; - -template -void testAlloc() { - try { - TestBenches heapTests{}; - heapTests.runTests(); - } catch (...) { - ASSERT(false); - } -} - -SUITE(Allocators) { - TEST(GlobalHeap) { testAlloc(); } - - TEST(Heap) { testAlloc(); } - - TEST(Chunk) { - testAlloc>(); - testAlloc>(); - } - - TEST(Pool) { - testAlloc>(); - testAlloc>(); - testAlloc>(); - } - - TEST(Simple) { - auto a = new TestStruct(-1); - delete a; - } -} - - -int main() { - - tp::ModuleManifest* deps[] = { &tp::gModuleAllocators, nullptr }; - tp::ModuleManifest testModule("AllocatorsTest", nullptr, nullptr, deps); - - if (!testModule.initialize()) { - return 1; - } - - bool res = UnitTest::RunAllTests(); - - testModule.deinitialize(); - - return res; -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fbc0ec6..f25dcac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,11 +11,9 @@ project(ModulesRoot) include(CMakeOptions.txt) add_subdirectory(Modules) -add_subdirectory(Callstack) add_subdirectory(Containers) add_subdirectory(Math) add_subdirectory(Strings) -add_subdirectory(Allocators) # add_subdirectory(Language) add_subdirectory(Externals) add_subdirectory(Connection) diff --git a/Callstack/CMakeLists.txt b/Callstack/CMakeLists.txt deleted file mode 100644 index d6ce6cc..0000000 --- a/Callstack/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -project(Callstack) - -### ---------------------- Static Library --------------------- ### -file(GLOB SOURCES "./private/*.cpp") - -add_library(${PROJECT_NAME} STATIC ${SOURCES}) -target_include_directories(${PROJECT_NAME} PUBLIC ./public/) -target_link_libraries(${PROJECT_NAME} PUBLIC Containers) - -### -------------------------- Tests -------------------------- ### -file(GLOB TEST_SOURCES "./tests/*.cpp") -add_executable(Tests${PROJECT_NAME} ${TEST_SOURCES}) -target_link_libraries(Tests${PROJECT_NAME} ${PROJECT_NAME} UnitTest++) -add_test(NAME Tests${PROJECT_NAME} COMMAND Tests${PROJECT_NAME}) \ No newline at end of file diff --git a/Callstack/private/Callstack.cpp b/Callstack/private/Callstack.cpp deleted file mode 100644 index 4897748..0000000 --- a/Callstack/private/Callstack.cpp +++ /dev/null @@ -1,338 +0,0 @@ - -#include "Callstack.hpp" - -#include - -using namespace tp; - -// frame to reference on no sapce left -static void errorNoSpaceLeft() { - // to disable optimization of function - static int dummy; - dummy = 10; -} - -ualni CallStackCapture::CallStack::getDepth() const { - ualni len = 0; - for (long long frame : frames) { - if (!frame) { - break; - } - len++; - } - return len++; -} - -ualni CallStackCapture::hashCallStack(CallStackKey key) { - auto const cs = key.cs; - ualni out = 0; - for (ualni i = 0; cs->frames[i]; i++) { - out += cs->frames[i]; - } - return out; -} - -bool CallStackCapture::CallStackKey::operator==(const CallStackCapture::CallStackKey& in) const { - for (ualni i = 0; i < MAX_CALL_DEPTH_CAPTURE; i++) { - if (cs->frames[i] != in.cs->frames[i]) { - return false; - } - if (cs->frames[i] == 0 && in.cs->frames[i] == 0) { - return true; - } - } - DEBUG_ASSERT(0 && "Must Not Happen") - return true; -} - -CallStackCapture::CallStackCapture() { - static_assert(MAX_CALL_DEPTH_CAPTURE >= 1); - static_assert(MAX_CALL_CAPTURES_MEM_SIZE_MB > 0); - static_assert(MAX_DEBUG_INFO_LEN > sizeof("unresolved")); - static_assert(MAX_CALL_CAPTURES_MEM_SIZE_MB * 1024 * 1024 > sizeof(CallStack)); - - mBuffLoad = 0; - mBuffLen = STACKS_LENGTH; - mBuff = (CallStack*) malloc(mBuffLen * sizeof(CallStack)); - - mErrorSnapshot.frames[0] = (alni) & errorNoSpaceLeft; - - - platformInit(); - - initialized = true; -} - -const CallStackCapture::CallStack* CallStackCapture::getSnapshot() { - - if (mBuffLoad > mBuffLen) { - return &mErrorSnapshot; - } - - CallStack* cs = &mBuff[mBuffLoad]; - - platformWriteStackTrace(cs); - - auto idx = mSnapshots.presents({ cs }); - if (idx) { - return mSnapshots.getSlotVal(idx); - } - - mSnapshots.put({ cs }, cs); - - mBuffLoad++; - return cs; -} - -const CallStackCapture::DebugSymbols* CallStackCapture::getSymbols(FramePointer frame) { - auto idx = mSymbols.presents(frame); - if (idx) { - return &mSymbols.getSlotVal(idx); - } - - mSymbols.put(frame, {}); - auto symbols = &mSymbols.get(frame); - - platformWriteDebugSymbols(frame, symbols); - return symbols; -} - -void CallStackCapture::clear() { - mBuffLoad = 0; - mSnapshots.removeAll(); - mSymbols.removeAll(); -} - -CallStackCapture::~CallStackCapture() { - free(mBuff); - initialized = false; -} - -// ---------------------------------- Platform Depended ---------------------------------- // - -#if defined(ENV_OS_LINUX) - -#include -#include -#include -#include - -void CallStackCapture::platformInit() { -} - -void CallStackCapture::platformDeinit() { -} - -void CallStackCapture::platformWriteStackTrace(CallStack* stack) { - auto depth = backtrace((void**) stack->frames, (int) MAX_CALL_DEPTH_CAPTURE - 1); - stack->frames[depth] = 0; -} - -static void getGetSourceFromBinaryAddress(const char* binary, const char* address, char* file, ualni* line) { - static char buff[1024]; - - snprintf(buff, sizeof(buff), "addr2line -e %s -a %s", binary, address); - FILE* pipe = popen(buff, "r"); - if (pipe) { - fgets(buff, sizeof(buff), pipe); - fgets(buff, sizeof(buff), pipe); - pclose(pipe); - char* linePtr = strchr(buff, ':'); - - printf("%s\n", buff); - - if (linePtr != nullptr && buff[0] != '?' && buff[1] != '?' && buff[2] != ':') { - *linePtr = '\0'; - auto sourceLen = std::strlen(buff); - std::strcpy(file, buff + ((sourceLen > CallStackCapture::MAX_DEBUG_INFO_LEN) ? (sourceLen - CallStackCapture::MAX_DEBUG_INFO_LEN) : 0)); - *line = strtoul(linePtr + 1, nullptr, 10); - return; - } - } - - std::strcpy(file, "unresolved"); - *line = 0; -} - -static void getDemangledName(const char* func, char* out) { - int status; - size_t funcDemangledSize = CallStackCapture::MAX_DEBUG_INFO_LEN; - char* funcDemangled = (char*) malloc(funcDemangledSize); - char* ret = abi::__cxa_demangle(func, funcDemangled, &funcDemangledSize, &status); - if (status == 0) { - funcDemangled = ret; - auto funcLen = std::strlen(funcDemangled); - std::strcpy(out, funcDemangled + ((funcLen > CallStackCapture::MAX_DEBUG_INFO_LEN) ? (funcLen - CallStackCapture::MAX_DEBUG_INFO_LEN) : 0)); - free(ret); - return; - } - auto funcLen = std::strlen(func); - std::strcpy(out, func + ((funcLen > CallStackCapture::MAX_DEBUG_INFO_LEN) ? (funcLen - CallStackCapture::MAX_DEBUG_INFO_LEN) : 0)); - free(funcDemangled); -} - -void CallStackCapture::platformWriteDebugSymbols(FramePointer frame, DebugSymbols* out) { - void* addrList[1] = { (void*) frame }; - auto symbolsArray = backtrace_symbols(addrList, 1); - - // 'bin(fun+addr)' - char* bin = *symbolsArray; - char* func = nullptr; - char* offset = nullptr; - - // 'bin fun+addr' - for (char* p = bin; *p; ++p) { - if (*p == '(') { - *p = 0; - func = p + 1; - } else if (*p == '+') { - offset = p; - } else if (*p == ')' && offset) { - *p = 0; - } - } - - if (func && offset) { - getGetSourceFromBinaryAddress(bin, func, out->file, &out->line); - - if (offset != func) { - *offset = 0; - getDemangledName(func, out->function); - } else { - std::strcpy(out->function, "unresolved"); - } - } else { - std::strcpy(out->file, "unresolved"); - std::strcpy(out->function, "unresolved"); - } - - free(symbolsArray); -} - -void CallStackCapture::printSnapshot(const CallStack* snapshot) { - printf("CallStack: \n"); - if (snapshot) { - for (auto frame : *snapshot) { - auto symbols = getSymbols(frame.getFrame()); - printf(" %s ----- %s:%llu\n", symbols->getFunc(), symbols->getFile(), symbols->getLine()); - } - } - printf("\n"); -} - -void CallStackCapture::logAll() { - for (auto cs : *this) { - printSnapshot(cs.getCallStack()); - } -} - -#else -#include -#include -#include - -#pragma comment(lib, "dbghelp.lib") - -void CallStackCapture::platformInit() { - HANDLE process = GetCurrentProcess(); - SymInitialize(process, NULL, TRUE); -} - -void CallStackCapture::platformDeinit() { - HANDLE process = GetCurrentProcess(); - SymCleanup(process); -} - -void CallStackCapture::platformWriteStackTrace(CallStack* stack) { - DWORD hash; - CONTEXT context; - memset(&context, 0, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_FULL; - RtlCaptureContext(&context); - - STACKFRAME64 stackFrame; - memset(&stackFrame, 0, sizeof(STACKFRAME64)); -#ifdef _M_IX86 - hash = IMAGE_FILE_MACHINE_I386; - stackFrame.AddrPC.Offset = context.Eip; - stackFrame.AddrPC.Mode = AddrModeFlat; - stackFrame.AddrFrame.Offset = context.Ebp; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrStack.Offset = context.Esp; - stackFrame.AddrStack.Mode = AddrModeFlat; -#elif _M_X64 - hash = IMAGE_FILE_MACHINE_AMD64; - stackFrame.AddrPC.Offset = context.Rip; - stackFrame.AddrPC.Mode = AddrModeFlat; - stackFrame.AddrFrame.Offset = context.Rbp; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrStack.Offset = context.Rsp; - stackFrame.AddrStack.Mode = AddrModeFlat; -#endif - - for (int frameIndex = 0; frameIndex < MAX_CALL_DEPTH_CAPTURE; ++frameIndex) { - if (!StackWalk64( - hash, - GetCurrentProcess(), - GetCurrentThread(), - &stackFrame, - &context, - NULL, - SymFunctionTableAccess64, - SymGetModuleBase64, - NULL - )) { - - stack->frames[frameIndex] = 0; - break; - } - stack->frames[frameIndex] = (alni) (void*) stackFrame.AddrPC.Offset; - } - stack->frames[MAX_CALL_DEPTH_CAPTURE - 1] = 0; -} - -void CallStackCapture::platformWriteDebugSymbols(FramePointer frame, DebugSymbols* out) { - HANDLE process = GetCurrentProcess(); - - IMAGEHLP_LINE64 lineInfo; - DWORD displacement; - lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - if (SymGetLineFromAddr64(process, (DWORD64) frame, &displacement, &lineInfo)) { - strcpy(out->file, lineInfo.FileName); - out->line = lineInfo.LineNumber; - } else { - strcpy(out->file, "unresolved"); - out->line = 0; - } - - DWORD64 displacementSym = 0; - char symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_PATH] = { 0 }; - IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*) symbolBuffer; - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - symbol->MaxNameLength = MAX_PATH; - - if (SymGetSymFromAddr64(process, (DWORD64) frame, &displacementSym, symbol)) { - strcpy(out->function, symbol->Name); - } else { - strcpy(out->function, "unresolved"); - } -} - -void CallStackCapture::printSnapshot(const CallStack* snapshot) { - printf("CallStack: \n"); - if (snapshot) { - for (int i = 0; i < snapshot->getDepth(); ++i) { - DebugSymbols symbols; - platformWriteDebugSymbols(snapshot->frames[i], &symbols); - printf(" %s ----- %s:%lu\n", symbols.function, symbols.file, symbols.line); - } - } - printf("\n"); -} - -void CallStackCapture::logAll() { - for (auto cs : *this) { - printSnapshot(cs.getCallStack()); - } -} -#endif \ No newline at end of file diff --git a/Callstack/public/Callstack.hpp b/Callstack/public/Callstack.hpp deleted file mode 100644 index aac0e3c..0000000 --- a/Callstack/public/Callstack.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include "Environment.hpp" -#include "Map.hpp" - -namespace tp { - - class CallStackCapture { - public: - typedef tp::alni FramePointer; - - bool initialized = false; - - enum { - MAX_CALL_DEPTH_CAPTURE = 16, - MAX_CALL_CAPTURES_MEM_SIZE_MB = 32, - MAX_DEBUG_INFO_LEN = 64, - }; - - class CallStack { - friend CallStackCapture; - FramePointer frames[MAX_CALL_DEPTH_CAPTURE]; - - public: - [[nodiscard]] ualni getDepth() const; - - class Iterator { - const FramePointer* mFrame; - - public: - explicit Iterator(const FramePointer* frame) : mFrame(frame){}; - FramePointer getFrame() { return *mFrame; } - bool operator==(const Iterator& in) const { return in.mFrame == mFrame; } - void operator++() { mFrame++; } - const Iterator& operator*() const { return *this; } - }; - - [[nodiscard]] Iterator begin() const { return Iterator(frames); } - [[nodiscard]] Iterator end() const { return Iterator(frames + getDepth()); } - }; - - enum { STACKS_LENGTH = (MAX_CALL_CAPTURES_MEM_SIZE_MB * 1024 * 1024) / sizeof(CallStack) }; - - class DebugSymbols { - friend CallStackCapture; - char function[MAX_DEBUG_INFO_LEN + 1] = { 0 }; - char file[MAX_DEBUG_INFO_LEN + 1] = { 0 }; - ualni line = 0; - - public: - [[nodiscard]] const char* getFunc() const { return function; } - [[nodiscard]] const char* getFile() const { return file; } - [[nodiscard]] ualni getLine() const { return line; } - }; - - public: - CallStackCapture(); - ~CallStackCapture(); - - [[nodiscard]] const CallStack* getSnapshot(); - const DebugSymbols* getSymbols(FramePointer fp); - - void printSnapshot(const CallStack* snapshot); - void logAll(); - - public: - class Iterator { - const CallStack* mSnapshot; - - public: - explicit Iterator(const CallStack* start) : mSnapshot(start) {}; - const CallStack* getCallStack() { return mSnapshot; } - bool operator==(const Iterator& in) const { return in.mSnapshot == mSnapshot; } - void operator++() { mSnapshot++; } - const Iterator& operator*() const { return *this; } - }; - - [[nodiscard]] Iterator begin() const { return Iterator(mBuff); } - [[nodiscard]] Iterator end() const { return Iterator(mBuff + mBuffLoad); } - - private: - struct CallStackKey { - CallStack* cs; - bool operator==(const CallStackKey& in) const; - }; - - static void platformWriteStackTrace(CallStack* stack); - static void platformWriteDebugSymbols(FramePointer frame, DebugSymbols* out); - [[nodiscard]] static ualni hashCallStack(CallStackKey key); - void platformInit(); - void platformDeinit(); - - void clear(); - - private: - CallStack mErrorSnapshot; - - ualni mBuffLen; - ualni mBuffLoad; - CallStack* mBuff; - - Map mSnapshots; - Map mSymbols; - }; -} diff --git a/Callstack/tests/Test.cpp b/Callstack/tests/Test.cpp deleted file mode 100644 index e5ed3b7..0000000 --- a/Callstack/tests/Test.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -#include "UnitTest++/UnitTest++.h" - -#include "Callstack.hpp" - -#include - -using namespace tp; - -void common(CallStackCapture& cs) { auto tmp = cs.getSnapshot(); } - -void first(CallStackCapture& cs) { - common(cs); - common(cs); - common(cs); -} - -void second(CallStackCapture& cs) { - common(cs); - common(cs); - common(cs); - common(cs); -} - -void third(CallStackCapture& cs) { - common(cs); - common(cs); -} - -void root(CallStackCapture& cs) { - first(cs); - second(cs); - third(cs); -} - -SUITE(Utils) { - TEST(CallStackCapture) { - CallStackCapture callstack; - root(callstack); - callstack.logAll(); - } -} - -int main() { return UnitTest::RunAllTests(); } \ No newline at end of file diff --git a/DataAnalysis/CMakeLists.txt b/DataAnalysis/CMakeLists.txt index 1463460..3f00bd3 100644 --- a/DataAnalysis/CMakeLists.txt +++ b/DataAnalysis/CMakeLists.txt @@ -11,7 +11,7 @@ file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp" "./applications/*.hpp") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) target_include_directories(${PROJECT_NAME} PUBLIC ./public/) -target_link_libraries(${PROJECT_NAME} PUBLIC Math Containers Allocators) +target_link_libraries(${PROJECT_NAME} PUBLIC Math Containers) ### -------------------------- Applications -------------------------- ### add_executable(NumRecTrain applications/NumRecTraining.cpp) diff --git a/DataAnalysis/private/DataAnalysisCommon.cpp b/DataAnalysis/private/DataAnalysisCommon.cpp deleted file mode 100644 index 1085e20..0000000 --- a/DataAnalysis/private/DataAnalysisCommon.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "DataAnalysisCommon.hpp" -#include "Allocators.hpp" -#include "ContainersCommon.hpp" -#include "MathCommon.hpp" - -namespace tp { - static ModuleManifest* deps[] = { &gModuleAllocators, nullptr }; - ModuleManifest gModuleDataAnalysis = ModuleManifest("DataAnalysis", nullptr, nullptr, deps); -} diff --git a/DataAnalysis/private/FCNN.cpp b/DataAnalysis/private/FCNN.cpp index 48d4fb4..be5b322 100644 --- a/DataAnalysis/private/FCNN.cpp +++ b/DataAnalysis/private/FCNN.cpp @@ -1,7 +1,6 @@ // #include "NewPlacement.hpp" #include "FCNN.hpp" -#include "Utils.hpp" #include diff --git a/DataAnalysis/public/DataAnalysisCommon.hpp b/DataAnalysis/public/DataAnalysisCommon.hpp deleted file mode 100644 index 8a1050c..0000000 --- a/DataAnalysis/public/DataAnalysisCommon.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "Module.hpp" - -namespace tp { - extern ModuleManifest gModuleDataAnalysis; -} diff --git a/DataAnalysis/public/FCNN.hpp b/DataAnalysis/public/FCNN.hpp index fd13076..b2dcf1b 100644 --- a/DataAnalysis/public/FCNN.hpp +++ b/DataAnalysis/public/FCNN.hpp @@ -1,7 +1,6 @@ #pragma once #include "Buffer.hpp" -#include "DataAnalysisCommon.hpp" namespace tp { // Fully connected neural network diff --git a/DataAnalysis/tests/Tests.cpp b/DataAnalysis/tests/Tests.cpp index a01e5ac..af7b914 100644 --- a/DataAnalysis/tests/Tests.cpp +++ b/DataAnalysis/tests/Tests.cpp @@ -60,16 +60,5 @@ SUITE(FCNN) { } int main() { - tp::ModuleManifest* deps[] = { &tp::gModuleDataAnalysis, nullptr }; - tp::ModuleManifest testModule("DataAnalysisTest", nullptr, nullptr, deps); - - if (!testModule.initialize()) { - return 1; - } - - bool res = UnitTest::RunAllTests(); - - testModule.deinitialize(); - - return res; + return UnitTest::RunAllTests(); } diff --git a/Graphics/CMakeLists.txt b/Graphics/CMakeLists.txt index 9794823..1159d2a 100644 --- a/Graphics/CMakeLists.txt +++ b/Graphics/CMakeLists.txt @@ -10,7 +10,7 @@ file(GLOB HEADERS "./public/*.hpp") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) target_include_directories(${PROJECT_NAME} PUBLIC ./public/) target_include_directories(${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE}) -target_link_libraries(${PROJECT_NAME} PUBLIC Math Allocators) +target_link_libraries(${PROJECT_NAME} PUBLIC Math) target_link_libraries(${PROJECT_NAME} PRIVATE ${BINDINGS_LIBS}) ### -------------------------- Examples -------------------------- ### diff --git a/Graphics/examples/Example.cpp b/Graphics/examples/Example.cpp index 935a1c4..021a159 100644 --- a/Graphics/examples/Example.cpp +++ b/Graphics/examples/Example.cpp @@ -21,18 +21,6 @@ public: }; int main() { - - ModuleManifest* deps[] = { &gModuleGraphics, nullptr }; - ModuleManifest module("Eample", nullptr, nullptr, deps); - - if (!module.initialize()) { - return 1; - } - - { - ExampleApplication app; - app.run(); - } - - module.deinitialize(); + ExampleApplication app; + app.run(); } diff --git a/Graphics/private/DebugGUI.cpp b/Graphics/private/DebugGUI.cpp index df779c0..35d5061 100644 --- a/Graphics/private/DebugGUI.cpp +++ b/Graphics/private/DebugGUI.cpp @@ -1,8 +1,6 @@ #include "Window.hpp" #include "WindowContext.hpp" -#include "Allocators.hpp" - #include "Graphics.hpp" // -------- Debug UI -------- // @@ -50,13 +48,9 @@ DebugGUI::~DebugGUI() { } void DebugGUI::drawBegin() { - tp::HeapAllocGlobal::startIgnore(); - ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - - tp::HeapAllocGlobal::stopIgnore(); } void DebugGUI::drawEnd() { diff --git a/Graphics/private/Window.cpp b/Graphics/private/Window.cpp index 87c54ae..affdea3 100644 --- a/Graphics/private/Window.cpp +++ b/Graphics/private/Window.cpp @@ -1,7 +1,6 @@ #include "Window.hpp" #include "WindowContext.hpp" -#include "Allocators.hpp" #include "Rect.hpp" @@ -18,11 +17,6 @@ #include #include -namespace tp { - static ModuleManifest* deps[] = { &gModuleAllocators, nullptr }; - ModuleManifest gModuleGraphics = ModuleManifest("Graphics", nullptr, nullptr, deps); -} - using namespace tp; static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); @@ -62,8 +56,6 @@ Window::~Window() { } Window* Window::createWindow(Vec2F size, const char* title) { - HeapAllocGlobal::startIgnore(); - static int count = 1; if (!count) { printf("Window class is a singleton\n"); @@ -82,7 +74,6 @@ Window* Window::createWindow(Vec2F size, const char* title) { auto out = new Window(size, title); - HeapAllocGlobal::stopIgnore(); return out; } diff --git a/Graphics/public/Window.hpp b/Graphics/public/Window.hpp index 43694ff..3399739 100644 --- a/Graphics/public/Window.hpp +++ b/Graphics/public/Window.hpp @@ -4,9 +4,6 @@ #include "EventHandler.hpp" namespace tp { - - extern ModuleManifest gModuleGraphics; - class Window { class Context; diff --git a/LibraryViewer/applications/Entry.cpp b/LibraryViewer/applications/Entry.cpp index a24a214..1545d69 100644 --- a/LibraryViewer/applications/Entry.cpp +++ b/LibraryViewer/applications/Entry.cpp @@ -40,24 +40,10 @@ private: LibraryWidget gui; }; -void runApp() { +int main() { tp::GlobalGUIConfig config; tp::gGlobalGUIConfig = &config; LibraryViewer lib; lib.run(); } - -int main() { - - tp::ModuleManifest* deps[] = { &tp::gModuleLibraryViewer, nullptr }; - tp::ModuleManifest binModule("LibViewEntry", nullptr, nullptr, deps); - - if (!binModule.initialize()) { - return 1; - } - - runApp(); - - binModule.deinitialize(); -} diff --git a/LibraryViewer/private/Library.cpp b/LibraryViewer/private/Library.cpp index 2d63696..4a66272 100644 --- a/LibraryViewer/private/Library.cpp +++ b/LibraryViewer/private/Library.cpp @@ -6,11 +6,6 @@ #include "picojson.h" #include -namespace tp { - static ModuleManifest* deps[] = { &gModuleGraphics, &gModuleStrings, &gModuleAllocators, nullptr }; - ModuleManifest gModuleLibraryViewer = ModuleManifest("LibraryViewer", nullptr, nullptr, deps); -} - using namespace tp; #define AS_STR (int1*) trackProperty.second.to_str().c_str() diff --git a/LibraryViewer/public/Library.hpp b/LibraryViewer/public/Library.hpp index 41e900d..0af0abf 100644 --- a/LibraryViewer/public/Library.hpp +++ b/LibraryViewer/public/Library.hpp @@ -10,10 +10,6 @@ tp::String getHome(); tp::String getSongLocalPath(SongId id); SONG_FORMAT getSongFormat(const tp::String& path); -namespace tp { - extern ModuleManifest gModuleLibraryViewer; -} - class Track { public: Track() = default; diff --git a/Objects/applications/GUIEntry.cpp b/Objects/applications/GUIEntry.cpp index 6c574c9..ad52ec7 100644 --- a/Objects/applications/GUIEntry.cpp +++ b/Objects/applications/GUIEntry.cpp @@ -26,7 +26,7 @@ private: int main() { - tp::ModuleManifest* deps[] = { &gModuleObjects, &gModuleGraphics, nullptr }; + tp::ModuleManifest* deps[] = { &gModuleObjects, nullptr }; tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps); if (module.initialize()) { diff --git a/Objects/private/core/objectsave.cpp b/Objects/private/core/objectsave.cpp index 0b66230..d490cc8 100644 --- a/Objects/private/core/objectsave.cpp +++ b/Objects/private/core/objectsave.cpp @@ -4,8 +4,6 @@ #include "primitives/nullobject.h" -#include "HeapAllocatorGlobal.hpp" - #include namespace obj { @@ -26,7 +24,7 @@ namespace obj { }; Object* ObjectMemAllocate(const ObjectType* type) { - ObjectMemHead* memh = (ObjectMemHead*) tp::HeapAllocGlobal::allocate(type->size + sizeof(ObjectMemHead)); + ObjectMemHead* memh = (ObjectMemHead*) malloc(type->size + sizeof(ObjectMemHead)); if (!memh) { return NULL; } @@ -62,7 +60,7 @@ namespace obj { bottom = memh->up; } - tp::HeapAllocGlobal::deallocate(memh); + free(memh); count--; } diff --git a/Objects/private/core/scriptsection.cpp b/Objects/private/core/scriptsection.cpp index e9f6447..31df1f5 100644 --- a/Objects/private/core/scriptsection.cpp +++ b/Objects/private/core/scriptsection.cpp @@ -1,6 +1,4 @@ -#include "HeapAllocatorGlobal.hpp" - #include "core/scriptsection.h" using namespace obj; @@ -17,7 +15,7 @@ void set_script_head_store_adress(Script* in, tp::alni address) { ((script_data_ tp::alni get_script_head_store_adress(Script* in) { return ((script_data_head*) in - 1)->store_adress; } Script* ScriptSection::createScript() { - auto sdhead = (script_data_head*) tp::HeapAllocGlobal::allocate(sizeof(script_data_head) + sizeof(Script)); + auto sdhead = (script_data_head*) malloc(sizeof(script_data_head) + sizeof(Script)); auto out = (Script*) (sdhead + 1); if (!sdhead) { @@ -39,7 +37,7 @@ void ScriptSection::delete_script(Script* script) { script->~Script(); obj::NDO->destroy(script->mReadable); - tp::HeapAllocGlobal::deallocate((((script_data_head*) script) - 1)); + free((((script_data_head*) script) - 1)); } void ScriptSection::reference_script(Script* script) { (((script_data_head*) script) - 1)->refc++; } diff --git a/Objects/private/interpreter/scopestack.cpp b/Objects/private/interpreter/scopestack.cpp index 33a40d7..6901f23 100644 --- a/Objects/private/interpreter/scopestack.cpp +++ b/Objects/private/interpreter/scopestack.cpp @@ -27,7 +27,7 @@ obj::Object* ScopeStack::getLocalUtil(Scope& scope, tp::String* id) { } ScopeStack::ScopeStack() { - mBuff = (Scope*) tp::HeapAllocGlobal::allocate(sizeof(Scope) * MAX_STACK_SIZE); + mBuff = (Scope*) malloc(sizeof(Scope) * MAX_STACK_SIZE); mIdx = 0; mIterIdx = 0; } @@ -80,4 +80,4 @@ obj::Object* ScopeStack::getLocal(tp::String& str) { Scope* ScopeStack::getCurrentScope() { return &mBuff[mIdx - 1]; } -ScopeStack::~ScopeStack() { tp::HeapAllocGlobal::deallocate(mBuff); } +ScopeStack::~ScopeStack() { free(mBuff); } diff --git a/Sketch3D/applications/Entry.cpp b/Sketch3D/applications/Entry.cpp index 8897fb8..6213afa 100644 --- a/Sketch3D/applications/Entry.cpp +++ b/Sketch3D/applications/Entry.cpp @@ -34,7 +34,7 @@ void runApp() { int main() { - tp::ModuleManifest* deps[] = { &tp::gModuleGraphics, &tp::gModuleStrings, &tp::gModuleWidgets, nullptr }; + tp::ModuleManifest* deps[] = { &tp::gModuleStrings, nullptr }; tp::ModuleManifest binModule("LibViewEntry", nullptr, nullptr, deps); if (!binModule.initialize()) { diff --git a/Strings/CMakeLists.txt b/Strings/CMakeLists.txt index f5577a7..c62330b 100644 --- a/Strings/CMakeLists.txt +++ b/Strings/CMakeLists.txt @@ -5,7 +5,7 @@ file(GLOB SOURCES "./private/*.cpp") file(GLOB HEADERS "./public/*.hpp") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) target_include_directories(${PROJECT_NAME} PUBLIC ./public/) -target_link_libraries(${PROJECT_NAME} PUBLIC Allocators Containers) +target_link_libraries(${PROJECT_NAME} PUBLIC Containers) ### -------------------------- Tests -------------------------- ### enable_testing() diff --git a/Strings/private/Strings.cpp b/Strings/private/Strings.cpp index ef8c81e..7441a2e 100644 --- a/Strings/private/Strings.cpp +++ b/Strings/private/Strings.cpp @@ -1,6 +1,5 @@ #include "Strings.hpp" -#include "Allocators.hpp" #include "Logging.hpp" using namespace tp; @@ -12,6 +11,6 @@ bool initialize(const ModuleManifest*) { void deinitialize(const ModuleManifest*) { Logger::deinitializeGlobal(); } -static tp::ModuleManifest* sModuleDependencies[] = { &tp::gModuleAllocators, nullptr }; +static tp::ModuleManifest* sModuleDependencies[] = { nullptr }; ModuleManifest tp::gModuleStrings = ModuleManifest("Strings", initialize, deinitialize, sModuleDependencies); \ No newline at end of file diff --git a/Strings/public/StringLogic.hpp b/Strings/public/StringLogic.hpp index 8c66eb3..a6baa10 100644 --- a/Strings/public/StringLogic.hpp +++ b/Strings/public/StringLogic.hpp @@ -1,10 +1,10 @@ #pragma once -#include "Allocators.hpp" #include "Buffer.hpp" #include "Utils.hpp" #include #include +#include namespace tp { diff --git a/Strings/public/Strings.hpp b/Strings/public/Strings.hpp index c731ae1..6593f87 100644 --- a/Strings/public/Strings.hpp +++ b/Strings/public/Strings.hpp @@ -1,6 +1,5 @@ #pragma once -#include "Allocators.hpp" #include "StringLogic.hpp" namespace tp { @@ -81,7 +80,7 @@ namespace tp { MAX_BOOL_STRING_LENGTH = 10, MAX_FLOAT_STRING_LENGTH = 10, }; - static PoolAlloc, STRINGS_POOL_SIZE> sStringPool; + static Data sNullString; private: @@ -100,16 +99,18 @@ namespace tp { incReference(mData); } + void* alloc() { return malloc(sizeof(StringData)); } + // Creates new string data from raw data pointer. // Does not own string buffer - string buffer will not be freed. Initializes as const memory. StringTemplate(const tChar* raw) { - mData = new (sStringPool.allocate(0)) StringData(raw, true); + mData = new (alloc()) StringData(raw, true); incReference(mData); } // Copies raw data and claims ownership over it StringTemplate(tChar* raw) { - mData = new (sStringPool.allocate(0)) StringData(raw); + mData = new (alloc()) StringData(raw); incReference(mData); } @@ -123,7 +124,7 @@ namespace tp { dp->mReferenceCount--; if (!dp->mReferenceCount) { mData->~StringData(); - sStringPool.deallocate(mData); + free(mData); } } @@ -150,7 +151,7 @@ namespace tp { // We have no rights to modify if someone references that memory too // So we need to create new copy of StringData if (mData->mReferenceCount > 1) { - mData = new (sStringPool.allocate(0)) StringData(mData->mBuff); + mData = new (alloc()) StringData(mData->mBuff); incReference(mData); return; } @@ -158,7 +159,7 @@ namespace tp { // Also if initial raw data was marked as const - create copy of raw data // Note - raw data will be lost at this point if no other record of such is stored if (mData->mIsConst) { - mData = new (sStringPool.allocate(0)) StringData(mData->mBuff); + mData = new (alloc()) StringData(mData->mBuff); incReference(mData); } } @@ -182,21 +183,21 @@ namespace tp { explicit StringTemplate(alni val) { tChar raw[MAX_INT_STRING_LENGTH]; Logic::convertValueToString(val, raw, MAX_INT_STRING_LENGTH); - mData = new (sStringPool.allocate(0)) StringData(raw); + mData = new (alloc()) StringData(raw); incReference(mData); } explicit StringTemplate(alnf val) { tChar raw[MAX_INT_STRING_LENGTH]; Logic::convertValueToString(val, raw, MAX_FLOAT_STRING_LENGTH); - mData = new (sStringPool.allocate(0)) StringData(raw); + mData = new (alloc()) StringData(raw); incReference(mData); } explicit StringTemplate(bool val) { tChar raw[MAX_INT_STRING_LENGTH]; Logic::convertValueToString(val, raw, MAX_BOOL_STRING_LENGTH); - mData = new (sStringPool.allocate(0)) StringData(raw); + mData = new (alloc()) StringData(raw); incReference(mData); } @@ -260,9 +261,6 @@ namespace tp { [[nodiscard]] bool getIsConstFlag() const { return mData->mIsConst; } }; - template - PoolAlloc, StringTemplate::STRINGS_POOL_SIZE> StringTemplate::sStringPool; - template StringData StringTemplate::sNullString; diff --git a/Widgets/examples/Entry.cpp b/Widgets/examples/Entry.cpp index 861b0be..c7fc1d1 100644 --- a/Widgets/examples/Entry.cpp +++ b/Widgets/examples/Entry.cpp @@ -23,23 +23,11 @@ private: }; int main() { - - tp::ModuleManifest* deps[] = { &tp::gModuleWidgets, nullptr }; - tp::ModuleManifest binModule("Chat", nullptr, nullptr, deps); - - if (!binModule.initialize()) { - return 1; - } + GlobalGUIConfig mConfig; + gGlobalGUIConfig = &mConfig; { - GlobalGUIConfig mConfig; - gGlobalGUIConfig = &mConfig; - - { - ExampleGUI gui; - gui.run(); - } + ExampleGUI gui; + gui.run(); } - - binModule.deinitialize(); } diff --git a/Widgets/private/WidgetConfig.cpp b/Widgets/private/WidgetConfig.cpp index 0f09b55..8984b72 100644 --- a/Widgets/private/WidgetConfig.cpp +++ b/Widgets/private/WidgetConfig.cpp @@ -5,7 +5,4 @@ namespace tp { GlobalGUIConfig* gGlobalGUIConfig = nullptr; - - ModuleManifest* deps[] = { &gModuleGraphics, &gModuleStrings, nullptr }; - ModuleManifest gModuleWidgets = ModuleManifest("Widgets", nullptr, nullptr, deps); } \ No newline at end of file diff --git a/Widgets/public/WidgetConfig.hpp b/Widgets/public/WidgetConfig.hpp index 77579ae..f531f6b 100644 --- a/Widgets/public/WidgetConfig.hpp +++ b/Widgets/public/WidgetConfig.hpp @@ -9,8 +9,6 @@ namespace tp { - extern ModuleManifest gModuleWidgets; - struct WidgetConfig { struct Node { enum Type { NONE, VAL, COL, REF };