From daee46967f9bed931567f0bbf1fda10bf96e3c78 Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Wed, 12 Jun 2019 14:37:53 +0200 Subject: [PATCH] Allow deque usage with and without callback. This seems to be only possible with two different function names, as variadic arguments and default arguments wont work together. --- lib/pls/include/pls/internal/data_structures/work_stealing_deque.h | 4 +++- lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h | 8 +++++++- lib/pls/include/pls/internal/scheduling/task.h | 2 +- test/data_structures_test.cpp | 43 +++++++++++++++++++++---------------------- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h b/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h index caec50f..d39496f 100644 --- a/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h +++ b/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h @@ -81,8 +81,10 @@ class work_stealing_deque { tail_{other.tail_.load()}, previous_tail_{other.previous_tail_} {} + template + T *push_tail(ARGS &&... args); template - T *push_tail(const Function &after_creation, ARGS &&... args); + T *push_tail_cb(const Function &after_creation, ARGS &&... args); Item *pop_tail(); Item *pop_head(); diff --git a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h index e1f15e2..d3316be 100644 --- a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h +++ b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h @@ -37,8 +37,14 @@ std::pair *work_stealing_deque::allocate_item } template +template +T *work_stealing_deque::push_tail(ARGS &&... args) { + return push_tail_cb([](T *) {}, std::forward(args)...); +} + +template template -T *work_stealing_deque::push_tail(const Function &after_creation, ARGS &&... args) { +T *work_stealing_deque::push_tail_cb(const Function &after_creation, ARGS &&... args) { static_assert(std::is_same::value || std::is_base_of::value, "Must only push types of onto work_stealing_deque"); diff --git a/lib/pls/include/pls/internal/scheduling/task.h b/lib/pls/include/pls/internal/scheduling/task.h index 6af295e..a589db0 100644 --- a/lib/pls/include/pls/internal/scheduling/task.h +++ b/lib/pls/include/pls/internal/scheduling/task.h @@ -50,7 +50,7 @@ void task::spawn_child(ARGS &&... args) { ref_count_++; // Push on our deque - thread_state::get()->deque_.push_tail([this](T *item) { + thread_state::get()->deque_.push_tail_cb([this](T *item) { // Assign forced values (for stack and parent management) item->parent_ = this; item->deque_state_ = thread_state::get()->deque_.save_state(); diff --git a/test/data_structures_test.cpp b/test/data_structures_test.cpp index dda7b26..962cb39 100644 --- a/test/data_structures_test.cpp +++ b/test/data_structures_test.cpp @@ -143,12 +143,11 @@ TEST_CASE("work stealing deque stores objects correctly", "[internal/data_struct work_stealing_deque deque{&stack}; int one = 1, two = 2, three = 3, four = 4; - auto no_op = [](int *) {}; // Empty-Callback SECTION("add and remove items form the tail") { - deque.push_tail(no_op, one); - deque.push_tail(no_op, two); - deque.push_tail(no_op, three); + deque.push_tail(one); + deque.push_tail(two); + deque.push_tail(three); REQUIRE(*deque.pop_tail() == three); REQUIRE(*deque.pop_tail() == two); @@ -156,17 +155,17 @@ TEST_CASE("work stealing deque stores objects correctly", "[internal/data_struct } SECTION("handles getting empty by popping the tail correctly") { - deque.push_tail(no_op, one); + deque.push_tail(one); REQUIRE(*deque.pop_tail() == one); - deque.push_tail(no_op, two); + deque.push_tail(two); REQUIRE(*deque.pop_tail() == two); } SECTION("remove items form the head") { - deque.push_tail(no_op, one); - deque.push_tail(no_op, two); - deque.push_tail(no_op, three); + deque.push_tail(one); + deque.push_tail(two); + deque.push_tail(three); REQUIRE(*deque.pop_head() == one); REQUIRE(*deque.pop_head() == two); @@ -174,47 +173,47 @@ TEST_CASE("work stealing deque stores objects correctly", "[internal/data_struct } SECTION("handles getting empty by popping the head correctly") { - deque.push_tail(no_op, one); + deque.push_tail(one); REQUIRE(*deque.pop_head() == one); - deque.push_tail(no_op, two); + deque.push_tail(two); REQUIRE(*deque.pop_head() == two); } SECTION("handles getting empty by popping the head and tail correctly") { - deque.push_tail(no_op, one); + deque.push_tail(one); REQUIRE(*deque.pop_tail() == one); - deque.push_tail(no_op, two); + deque.push_tail(two); REQUIRE(*deque.pop_head() == two); - deque.push_tail(no_op, three); + deque.push_tail(three); REQUIRE(*deque.pop_tail() == three); } SECTION("handles jumps bigger 1 correctly") { - deque.push_tail(no_op, one); - deque.push_tail(no_op, two); + deque.push_tail(one); + deque.push_tail(two); REQUIRE(*deque.pop_tail() == two); - deque.push_tail(no_op, three); - deque.push_tail(no_op, four); + deque.push_tail(three); + deque.push_tail(four); REQUIRE(*deque.pop_head() == one); REQUIRE(*deque.pop_head() == three); REQUIRE(*deque.pop_head() == four); } SECTION("handles stack reset 1 correctly when emptied by tail") { - deque.push_tail(no_op, one); + deque.push_tail(one); auto state = deque.save_state(); - deque.push_tail(no_op, two); + deque.push_tail(two); REQUIRE(*deque.pop_tail() == two); deque.release_memory_until(state); REQUIRE(*deque.pop_tail() == one); - deque.push_tail(no_op, three); - deque.push_tail(no_op, four); + deque.push_tail(three); + deque.push_tail(four); REQUIRE(*deque.pop_head() == three); REQUIRE(*deque.pop_tail() == four); } -- libgit2 0.26.0