diff --git a/CMakeLists.txt b/CMakeLists.txt index 93a7578..54c0bbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.85) +project(blt-gp VERSION 0.0.86) include(CTest) diff --git a/examples/gp_test_1.cpp b/examples/gp_test_1.cpp index 6114998..641ea8b 100644 --- a/examples/gp_test_1.cpp +++ b/examples/gp_test_1.cpp @@ -279,28 +279,33 @@ float nyah(float a, int b, bool c) return a + static_cast(b) * c; } -struct silly +struct bytes_16_struct { unsigned long bruh; int nya; - friend std::ostream& operator<<(std::ostream& out, const silly& s) + friend std::ostream& operator<<(std::ostream& out, const bytes_16_struct& s) { out << "[" << s.bruh << " " << s.nya << "]"; return out; } }; -struct large +struct bytes_256_struct { unsigned char data[256]; }; -struct super_large +struct bytes_5129_struct { unsigned char data[5129]; }; +struct bytes_4096_page_struct +{ + unsigned char data[4096 - 32]; +}; + struct context { float x, y; @@ -330,8 +335,8 @@ int main() { constexpr blt::size_t MAX_ALIGNMENT = 8; test(); - std::cout << alignof(silly) << " " << sizeof(silly) << std::endl; - std::cout << alignof(super_large) << " " << sizeof(super_large) << " " << ((sizeof(super_large) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1)) + std::cout << alignof(bytes_16_struct) << " " << sizeof(bytes_16_struct) << std::endl; + std::cout << alignof(bytes_5129_struct) << " " << sizeof(bytes_5129_struct) << " " << ((sizeof(bytes_5129_struct) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1)) << std::endl; std::cout << ((sizeof(char) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1)) << " " << ((sizeof(short) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1)) << std::endl; @@ -359,33 +364,53 @@ int main() std::cout << std::endl; std::cout << "Is empty? " << alloc.empty() << std::endl; - alloc.push(silly{}); - alloc.push(large{}); - alloc.push(super_large{}); - alloc.push(silly{25, 24}); - alloc.push(large{}); + + alloc.push(bytes_4096_page_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.push(bytes_16_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.pop(); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.pop(); + std::cout << "Used bytes: " << alloc.size() << std::endl; std::cout << std::endl; - std::cout << "Is empty? " << alloc.empty() << std::endl; - alloc.pop(); - std::cout << "Is empty? " << alloc.empty() << std::endl; - std::cout << alloc.pop() << std::endl; - std::cout << "Is empty? " << alloc.empty() << std::endl; - alloc.pop(); - std::cout << "Is empty? " << alloc.empty() << std::endl; - alloc.pop(); - std::cout << "Is empty? " << alloc.empty() << std::endl; - std::cout << alloc.pop() << std::endl; + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; std::cout << std::endl; + alloc.push(bytes_16_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.push(bytes_256_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.push(bytes_5129_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.push(bytes_16_struct{25, 24}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + alloc.push(bytes_256_struct{}); + std::cout << "Used bytes: " << alloc.size() << std::endl; + + std::cout << std::endl; + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; + alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; + std::cout << alloc.pop() << std::endl; + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; + alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; + alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << " " << alloc.size() << std::endl; + std::cout << alloc.pop() << std::endl; + std::cout << std::endl; + + std::cout << "Is empty? " << alloc.empty() << " bytes left: " << alloc.bytes_in_head() << std::endl; std::cout << std::endl; - alloc.push(silly{2, 5}); - alloc.push(large{}); - alloc.push(super_large{}); - alloc.push(silly{80, 10}); - alloc.push(large{}); + alloc.push(bytes_16_struct{2, 5}); + alloc.push(bytes_256_struct{}); + alloc.push(bytes_5129_struct{}); + alloc.push(bytes_16_struct{80, 10}); + alloc.push(bytes_256_struct{}); alloc.push(50); alloc.push(550.3f); alloc.push(20.1230345); diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 6d8225d..61fd2f2 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace blt::gp { @@ -150,7 +151,36 @@ namespace blt::gp blt::size_t total_used_bytes = 0; blt::size_t total_remaining_bytes = 0; blt::size_t total_no_meta_bytes = 0; + + blt::size_t total_dealloc = 0; + blt::size_t total_dealloc_used = 0; + blt::size_t total_dealloc_remaining = 0; + blt::size_t total_dealloc_no_meta = 0; + blt::size_t blocks = 0; + + friend std::ostream& operator<<(std::ostream& stream, const size_data_t& data) + { + stream << "["; + stream << data.total_used_bytes << "/"; + stream << data.total_size_bytes << "("; + stream << (static_cast(data.total_used_bytes) / static_cast(data.total_size_bytes)) << "%), "; + stream << data.total_used_bytes << "/"; + stream << data.total_no_meta_bytes << "("; + stream << (static_cast(data.total_used_bytes) / static_cast(data.total_no_meta_bytes)) << "%), (empty space: "; + stream << data.total_remaining_bytes << ") blocks: " << data.blocks << " || unallocated space: "; + stream << data.total_dealloc_used << "/"; + stream << data.total_dealloc; + if (static_cast(data.total_dealloc) > 0) + stream << "(" << (static_cast(data.total_dealloc_used) / static_cast(data.total_dealloc)) << "%)"; + stream << ", "; + stream << data.total_dealloc_used << "/"; + stream << data.total_dealloc_no_meta; + if (data.total_dealloc_no_meta > 0) + stream << "(" << (static_cast(data.total_dealloc_used) / static_cast(data.total_dealloc_no_meta)) << "%)"; + stream << ", (empty space: " << data.total_dealloc_remaining << ")]"; + return stream; + } }; @@ -178,11 +208,11 @@ namespace blt::gp constexpr static auto TYPE_SIZE = aligned_size(); if (head == nullptr) throw std::runtime_error("Silly boi the stack is empty!"); - if (head->used_bytes_in_block() < static_cast(aligned_size())) - throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( - head->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(NO_REF_T))).c_str()); if (head->used_bytes_in_block() == 0) move_back(); + if (head->used_bytes_in_block() < static_cast(aligned_size())) + throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( + head->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(NO_REF_T))).c_str()); // make copy NO_REF_T t = *reinterpret_cast(head->metadata.offset - TYPE_SIZE); // call destructor @@ -288,7 +318,8 @@ namespace blt::gp { blt::size_t offset = 0; - ((from>(offset).~NO_REF_T(), offset += stack_allocator::aligned_size>()), ...); + ((from < NO_REF_T < Args >> (offset).~NO_REF_T(), offset += stack_allocator::aligned_size> + ()), ...); } [[nodiscard]] bool empty() const @@ -314,15 +345,28 @@ namespace blt::gp [[nodiscard]] size_data_t size() { size_data_t size_data; - auto* next = head; - while (next != nullptr) + auto* prev = head; + while (prev != nullptr) { - size_data.total_size_bytes += next->metadata.size; - size_data.total_no_meta_bytes += next->storage_size(); - size_data.total_remaining_bytes += next->remaining_bytes_in_block(); - size_data.total_used_bytes += next->used_bytes_in_block(); + size_data.total_size_bytes += prev->metadata.size; + size_data.total_no_meta_bytes += prev->storage_size(); + size_data.total_remaining_bytes += prev->remaining_bytes_in_block(); + size_data.total_used_bytes += prev->used_bytes_in_block(); size_data.blocks++; - next = next->metadata.next; + prev = prev->metadata.prev; + } + if (head != nullptr) + { + auto next = head->metadata.next; + while (next != nullptr) + { + size_data.total_dealloc += next->metadata.size; + size_data.total_dealloc_no_meta += next->storage_size(); + size_data.total_dealloc_remaining += next->remaining_bytes_in_block(); + size_data.total_dealloc_used += next->used_bytes_in_block(); + size_data.blocks++; + next = next->metadata.next; + } } return size_data; } @@ -436,7 +480,7 @@ namespace blt::gp template void* allocate_bytes() { - return allocate_bytes(sizeof(NO_REF_T)); + return allocate_bytes(sizeof(NO_REF_T < T > )); } void* allocate_bytes(blt::size_t size)