diff --git a/Makefile b/Makefile index 9b79ffe..0e44a1b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CXX= clang++-10 -CXXFLAGS= --std=c++17 -O3 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -DNO_BENCH=0 -pedantic -Werror \ +CXXFLAGS= --std=c++17 -O0 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -DNO_BENCH=0 -pedantic -Werror \ -Wno-unknown-attributes -frtti \ -g -fprofile-instr-generate -fcoverage-mapping \ -fsanitize=address -fno-omit-frame-pointer diff --git a/include/gp/indexed_array.hpp b/include/gp/indexed_array.hpp index 2080bfb..fcf5a71 100644 --- a/include/gp/indexed_array.hpp +++ b/include/gp/indexed_array.hpp @@ -20,7 +20,8 @@ namespace gp{ public: indexed_array() {} - size_t push(T&& value) { + template + size_t push(U&& value) { size_t index; gp_config::assertion(data_top+1 != _capacity, "Indexed array capacity exceeded"); @@ -32,7 +33,7 @@ namespace gp{ index = data_top; } - new(&(data_table.as_buffer().template cast()[data_top])) T(gp::move(value)); + new(&(data_table.as_buffer().template cast()[data_top])) T(gp::forward(value)); translation_table[index] = data_top; reverse_translation_table[data_top] = index; diff --git a/include/gp/ring_list.hpp b/include/gp/ring_list.hpp index f350061..ae885ec 100644 --- a/include/gp/ring_list.hpp +++ b/include/gp/ring_list.hpp @@ -130,16 +130,17 @@ namespace gp { return any_node; } - void remove(explorer& value) { + void remove(explorer value) { auto v = value.pos; if(v == any_node) { if(v->next == v) { any_node = nullptr; } else { - stitch_around(any_node); + any_node = any_node->next; + stitch_around(v); } } else { - stitch_around(value.pos); + stitch_around(v); } allocator& used_allocator = alloc; v->value->~T(); @@ -147,5 +148,11 @@ namespace gp { v->~node(); gp_config::assertion(used_allocator.deallocate(v), "Bad free of node"); } + + ~ring_list() { + while(any_node) { + remove(explore()); + } + } }; } diff --git a/tests/gp_test.cpp b/tests/gp_test.cpp index e949246..a6de2f0 100644 --- a/tests/gp_test.cpp +++ b/tests/gp_test.cpp @@ -697,55 +697,102 @@ struct alloc_bench_test : public test_scaffold { virtual int run() { int res = 0; - auto store = std::make_unique>(); - using buddy_loc = gp::buddy<>; - using arena_loc = gp::arena<>; - buddy_loc bud{&*store->begin(), store->size()}; - arena_loc are{&*store->begin(), store->size()}; - - - for(size_t divider = 2; divider < 32; ++divider) - { - gp::ring_list a{bud}; - gp::ring_list b{are}; - - std::cout << - "ARE | " << "INS | " << divider << " | " << - time_operation([&](){ - for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { - b.insert(i); - } - }).count() << std::endl; - - std::cout << - "ARE | " << "DEL | " << divider << " | " << - time_operation([&](){ - for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { - gp::ring_list::explorer e = b.explore(); - b.remove(e); - } - }).count() << std::endl; + if(do_bench) { + auto store = std::make_unique>(); + using buddy_loc = gp::buddy<>; + using arena_loc = gp::arena<>; + buddy_loc bud{&*store->begin(), store->size()}; + arena_loc are{&*store->begin(), store->size()}; + + std::cout << "Allocator | Operation | Divider | Time (µs)" << std::endl; + + for(size_t divider = 2; divider < 32; ++divider) + { + gp::ring_list a{bud}; + gp::ring_list b{are}; + + std::cout << + "ARE | " << "INS | " << divider << " | " << + time_operation([&](){ + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + b.insert(i); + } + }).count() << std::endl; + + std::cout << + "ARE | " << "DEL | " << divider << " | " << + time_operation([&](){ + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + gp::ring_list::explorer e = b.explore(); + b.remove(e); + } + }).count() << std::endl; - std::cout << - "BUD | " << "INS | " << divider << " | " << - time_operation([&](){ - for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + std::cout << + "BUD | " << "INS | " << divider << " | " << + time_operation([&](){ + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + a.insert(i); + } + }).count() << std::endl; + + std::cout << + "BUD | " << "DEL | " << divider << " | " << + time_operation([&](){ + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + gp::ring_list::explorer e = a.explore(); + a.remove(e); + } + }).count() << std::endl; + } + { + gp::ring_list a{bud}; + gp::ring_list b{are}; + + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/2; i++) { a.insert(i); } - }).count() << std::endl; - std::cout << - "BUD | " << "DEL | " << divider << " | " << - time_operation([&](){ - for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/divider; i++) { + for(size_t i = 0; i < store->size()/sizeof(gp::ring_list::node)/2; i++) { gp::ring_list::explorer e = a.explore(); - a.remove(e); + a.remove(++e); } - }).count() << std::endl; + } } return res; } }; -append_test dummy_jhgspo5d5(new alloc_bench_test{}); \ No newline at end of file +append_test dummy_jhgspo5d5(new alloc_bench_test{}); + +struct indexed_array_stair_test : public test_scaffold { + indexed_array_stair_test() { + name = __FILE__ ":13"; + } + + virtual int run() { + int res = 0; + { + int climb = 0; + int curr_climb = 0; + gp::indexed_array arr; + while(climb < 1000) + { + for(; curr_climb < 10; climb++, curr_climb++ ) + { + arr.push(climb); + } + + for(; curr_climb != 0; curr_climb -= 2) { + arr.pop(arr.size() - curr_climb); + } + + arr.pop(arr.size() - 1); + } + } + return res; + } +}; + +append_test dummy_amf763ld5(new indexed_array_stair_test{}); \ No newline at end of file