diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 93c5cff..49a0a14 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -263,7 +263,7 @@ namespace snmalloc { lazy_decommit(); } - } while (old_epoch <= new_epoch); + } while (old_epoch < new_epoch); } } #endif diff --git a/src/test/perf/low_memory/low-memory.cc b/src/test/perf/low_memory/low-memory.cc new file mode 100644 index 0000000..4bff188 --- /dev/null +++ b/src/test/perf/low_memory/low-memory.cc @@ -0,0 +1,127 @@ +#include +#include +#include +#include + +#include +#include + +using namespace snmalloc; + +struct Node +{ + Node* next; +}; + +class Queue +{ + Node* head; + Node* tail; + + Node* new_node(size_t size) + { + auto result = (Node*)ThreadAlloc::get()->alloc(size); + result->next = nullptr; + return result; + } + +public: + Queue() + { + head = new_node(1); + tail = head; + } + + void add(size_t size) + { + tail->next = new_node(size); + tail = tail->next; + } + + void try_remove() + { + if (head->next == nullptr) + return; + + Node* next = head->next; + ThreadAlloc::get()->dealloc(head); + head = next; + } + +}; + +bool has_pressure() +{ + static thread_local uint64_t epoch; + + if constexpr (!pal_supports) + { + return false; + } + + uint64_t current_epoch = default_memory_provider.low_memory_epoch(); + bool result = epoch != current_epoch; + epoch = current_epoch; + return result; +} + + +void reach_pressure(Queue& allocations) +{ + size_t size = 1; + size_t i = 0; + while(!has_pressure()) + { + i++; + allocations.add(size); + allocations.try_remove(); + allocations.add(size); + + if (i % 8192 == 0) + size ++; + } +} + +void reduce_pressure(Queue& allocations) +{ + size_t size = 1; + size_t i = 0; + + for (size_t n = 0; n < 1000; n++) + { + allocations.try_remove(); + allocations.try_remove(); + allocations.add(size); + + if (i % 8192 == 0) + size ++; + } +} + + +int main(int, char**) +{ + + Queue allocations; + + + if constexpr (!pal_supports) + { + std::cout << "Pal does not support low-memory notification! Test not run" + << std::endl; + return 0; + } + + setup(); + + for(size_t i = 0; i < 10; i++) + { + reach_pressure(allocations); + std::cout << "Pressure " << i << std::endl; + + reduce_pressure(allocations); + + } + + return 0; +} \ No newline at end of file