diff --git a/CMakeLists.txt b/CMakeLists.txt index 644f159..23de5e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.94) +project(blt-gp VERSION 0.0.95) include(CTest) diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 2129f9d..56cbbcb 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -61,20 +61,20 @@ namespace blt::gp 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 << (static_cast(data.total_used_bytes) / static_cast(data.total_size_bytes) * 100) << "%), "; 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 << (static_cast(data.total_used_bytes) / static_cast(data.total_no_meta_bytes) * 100) << "%), (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 << "(" << (static_cast(data.total_dealloc_used) / static_cast(data.total_dealloc) * 100) << "%)"; 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 << "(" << (static_cast(data.total_dealloc_used) / static_cast(data.total_dealloc_no_meta * 100)) << "%)"; stream << ", (empty space: " << data.total_dealloc_remaining << ")]"; return stream; } diff --git a/lib/blt b/lib/blt index 27d1b94..4114de7 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 27d1b94493eb80982a4a46f80dae30cbea7e14bc +Subproject commit 4114de74dbb46b6e8f9663e63c430e31ca2f9b00 diff --git a/tests/stack_tests.cpp b/tests/stack_tests.cpp index bde268b..54b1652 100644 --- a/tests/stack_tests.cpp +++ b/tests/stack_tests.cpp @@ -16,8 +16,52 @@ * along with this program. If not, see . */ #include +#include #include #include +#include +#include +#include + +template +T make_data(T t, Func&& func) +{ + for (const auto& [index, v] : blt::enumerate(t.data)) + v = func(index); + return t; +} + +template +blt::ptrdiff_t compare(const T& t, const U& u) +{ + for (const auto& [index, v] : blt::enumerate(t.data)) + { + if (u.data[index] != v) + return static_cast(index); + } + return -1; +} + +#define MAKE_VARIABLE(SIZE) large_##SIZE base_##SIZE = make_data(large_##SIZE{}, [](auto index) { \ + return static_cast(blt::random::murmur_random64c(SEED + index, 0, 256)); \ +}); \ +large_##SIZE secondary_##SIZE = make_data(large_##SIZE{}, [](auto index) { \ + return static_cast(blt::random::murmur_random64c(SEED + index, 0, 256)); \ +}); \ +large_##SIZE tertiary_##SIZE = make_data(large_##SIZE{}, [](auto index) { \ + return static_cast(blt::random::murmur_random64c(SEED + index, 0, 256)); \ +}) + +#define RUN_TEST(FAILURE_COND, PASS, ...) do { if (FAILURE_COND) { BLT_ERROR(__VA_ARGS__); } else { BLT_DEBUG(PASS); } } while(false) +#define RUN_TEST_SIZE(VALUE, SIZE, STACK) RUN_TEST(auto index = compare(VALUE, STACK.pop()); index >= 0, #SIZE " Test PASSED.", "Failed to pop large value (" #SIZE "), failed at index %ld", index) +#define RUN_TEST_TYPE(TYPE, EXPECTED, STACK) RUN_TEST(auto val = STACK.pop(); val != EXPECTED, #TYPE " test PASSED", "Failed to pop correct " #TYPE " (" #EXPECTED ") found %lf", val); + +const blt::u64 SEED = std::random_device()(); + +struct large_256 +{ + blt::u8 data[256]; +}; struct large_2048 { @@ -39,21 +83,126 @@ struct large_18290 blt::u8 data[18290]; }; -template -T make_data(T t) -{ - for (const auto& [index, v] : blt::enumerate(t.data)) - { - v = index % 256; - } - return t; -} +MAKE_VARIABLE(256); +MAKE_VARIABLE(2048); +MAKE_VARIABLE(4096); +MAKE_VARIABLE(6123); +MAKE_VARIABLE(18290); void test_basic_types() { + BLT_INFO("Testing pushing types, will transfer and pop off each stack."); blt::gp::stack_allocator stack; stack.push(50.0f); - stack.push(make_data(large_2048{})); + BLT_TRACE_STREAM << "Pushed float: " << stack.size() << "\n"; + stack.push(base_2048); + BLT_TRACE_STREAM << "Pushed 2048: " << stack.size() << "\n"; + stack.push(25.0f); + BLT_TRACE_STREAM << "Pushed float: " << stack.size() << "\n"; + stack.push(-24.0f); + BLT_TRACE_STREAM << "Pushed float: " << stack.size() << "\n"; + stack.push(base_256); + BLT_TRACE_STREAM << "Pushed 256: " << stack.size() << "\n"; + stack.push(secondary_256); + BLT_TRACE_STREAM << "Pushed 256*: " << stack.size() << "\n"; + stack.push(false); + BLT_TRACE_STREAM << "Pushed bool: " << stack.size() << "\n"; + stack.push(523); + BLT_TRACE_STREAM << "Pushed int: " << stack.size() << "\n"; + stack.push(base_6123); + BLT_TRACE_STREAM << "Pushed 6123: " << stack.size() << "\n"; + + std::cout << std::endl; + + { + BLT_INFO("Popping 6123, int, and bool via transfer"); + blt::gp::stack_allocator to; + stack.transfer_bytes(to, sizeof(large_6123)); + stack.transfer_bytes(to, sizeof(int)); + stack.transfer_bytes(to, sizeof(bool)); + RUN_TEST_TYPE(bool, false, to); + RUN_TEST_TYPE(int, 523, to); + RUN_TEST_SIZE(base_6123, large_6123, to); + + BLT_ASSERT(to.empty() && "Stack isn't empty despite all values popped!"); + } + + BLT_TRACE_STREAM << stack.size() << "\n"; + std::cout << std::endl; + + BLT_INFO("Pushing new data onto partially removed stack, this will test re-allocating blocks. We will also push at least one more block."); + stack.push(tertiary_256); + BLT_TRACE_STREAM << "Pushed 256^: " << stack.size() << "\n"; + stack.push(69.999); + BLT_TRACE_STREAM << "Pushed double: " << stack.size() << "\n"; + stack.push(secondary_2048); + BLT_TRACE_STREAM << "Pushed 2048*: " << stack.size() << "\n"; + stack.push(420.6900001); + BLT_TRACE_STREAM << "Pushed double: " << stack.size() << "\n"; + stack.push(base_256); + BLT_TRACE_STREAM << "Pushed 256: " << stack.size() << "\n"; + stack.push(base_18290); + BLT_TRACE_STREAM << "Pushed 18290: " << stack.size() << "\n"; + std::cout << std::endl; + + { + BLT_INFO("Popping all data via transfer."); + blt::gp::stack_allocator to; + stack.transfer_bytes(to, sizeof(large_18290)); + stack.transfer_bytes(to, sizeof(large_256)); + stack.transfer_bytes(to, sizeof(double)); + stack.transfer_bytes(to, sizeof(large_2048)); + stack.transfer_bytes(to, sizeof(double)); + stack.transfer_bytes(to, sizeof(large_256)); + + RUN_TEST_SIZE(tertiary_256, large_256, to); + RUN_TEST_TYPE(double, 69.999, to); + RUN_TEST_SIZE(secondary_2048, large_2048, to); + RUN_TEST_TYPE(double, 420.6900001, to); + RUN_TEST_SIZE(base_256, large_256, to); + RUN_TEST_SIZE(base_18290, large_18290, to); + + BLT_ASSERT(to.empty() && "Stack isn't empty despite all values popped!"); + } + + BLT_TRACE_STREAM << stack.size() << "\n"; + std::cout << std::endl; + + BLT_INFO("Now we will test using large values where the unallocated blocks do not have enough storage."); + stack.push(secondary_18290); + BLT_TRACE_STREAM << "Pushed 18290*: " << stack.size() << "\n"; + stack.push(base_4096); + BLT_TRACE_STREAM << "Pushed 4096: " << stack.size() << "\n"; + stack.push(tertiary_18290); + BLT_TRACE_STREAM << "Pushed 18290^: " << stack.size() << "\n"; + stack.push(secondary_6123); + BLT_TRACE_STREAM << "Pushed 6123*: " << stack.size() << "\n"; + std::cout << std::endl; + + { + BLT_INFO("Popping values normally."); + RUN_TEST_SIZE(secondary_6123, large_6123, stack); + RUN_TEST_SIZE(tertiary_18290, large_18290, stack); + RUN_TEST_SIZE(base_4096, large_4096, stack); + RUN_TEST_SIZE(secondary_18290, large_18290, stack); + } + BLT_TRACE_STREAM << stack.size() << "\n"; + std::cout << std::endl; + + BLT_INFO("Some fishy numbers in the last reported size. Let's try modifying the stack."); + stack.push(88.9f); + BLT_TRACE_STREAM << "Pushed float: " << stack.size() << "\n"; + + { + BLT_INFO("Popping a few values."); + RUN_TEST_TYPE(float, 88.9f, stack); + BLT_TRACE_STREAM << "popped float: " << stack.size() << "\n"; + RUN_TEST_SIZE(secondary_256, large_256, stack); + } + BLT_TRACE_STREAM << stack.size() << "\n"; + std::cout << std::endl; + + } int main()