Commit daee4696 by FritzFlorian

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.
parent 51b919f0
......@@ -81,8 +81,10 @@ class work_stealing_deque {
tail_{other.tail_.load()},
previous_tail_{other.previous_tail_} {}
template<typename T, typename ...ARGS>
T *push_tail(ARGS &&... args);
template<typename T, typename Function, typename ...ARGS>
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();
......
......@@ -37,8 +37,14 @@ std::pair<work_stealing_deque_item, T> *work_stealing_deque<Item>::allocate_item
}
template<typename Item>
template<typename T, typename ...ARGS>
T *work_stealing_deque<Item>::push_tail(ARGS &&... args) {
return push_tail_cb<T>([](T *) {}, std::forward<ARGS>(args)...);
}
template<typename Item>
template<typename T, typename Function, typename ...ARGS>
T *work_stealing_deque<Item>::push_tail(const Function &after_creation, ARGS &&... args) {
T *work_stealing_deque<Item>::push_tail_cb(const Function &after_creation, ARGS &&... args) {
static_assert(std::is_same<Item, T>::value || std::is_base_of<Item, T>::value,
"Must only push types of <Item> onto work_stealing_deque<Item>");
......
......@@ -50,7 +50,7 @@ void task::spawn_child(ARGS &&... args) {
ref_count_++;
// Push on our deque
thread_state::get()->deque_.push_tail<T>([this](T *item) {
thread_state::get()->deque_.push_tail_cb<T>([this](T *item) {
// Assign forced values (for stack and parent management)
item->parent_ = this;
item->deque_state_ = thread_state::get()->deque_.save_state();
......
......@@ -143,12 +143,11 @@ TEST_CASE("work stealing deque stores objects correctly", "[internal/data_struct
work_stealing_deque<int> 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<int>(no_op, one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(no_op, three);
deque.push_tail<int>(one);
deque.push_tail<int>(two);
deque.push_tail<int>(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<int>(no_op, one);
deque.push_tail<int>(one);
REQUIRE(*deque.pop_tail() == one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(two);
REQUIRE(*deque.pop_tail() == two);
}
SECTION("remove items form the head") {
deque.push_tail<int>(no_op, one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(no_op, three);
deque.push_tail<int>(one);
deque.push_tail<int>(two);
deque.push_tail<int>(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<int>(no_op, one);
deque.push_tail<int>(one);
REQUIRE(*deque.pop_head() == one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(two);
REQUIRE(*deque.pop_head() == two);
}
SECTION("handles getting empty by popping the head and tail correctly") {
deque.push_tail<int>(no_op, one);
deque.push_tail<int>(one);
REQUIRE(*deque.pop_tail() == one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(two);
REQUIRE(*deque.pop_head() == two);
deque.push_tail<int>(no_op, three);
deque.push_tail<int>(three);
REQUIRE(*deque.pop_tail() == three);
}
SECTION("handles jumps bigger 1 correctly") {
deque.push_tail<int>(no_op, one);
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(one);
deque.push_tail<int>(two);
REQUIRE(*deque.pop_tail() == two);
deque.push_tail<int>(no_op, three);
deque.push_tail<int>(no_op, four);
deque.push_tail<int>(three);
deque.push_tail<int>(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<int>(no_op, one);
deque.push_tail<int>(one);
auto state = deque.save_state();
deque.push_tail<int>(no_op, two);
deque.push_tail<int>(two);
REQUIRE(*deque.pop_tail() == two);
deque.release_memory_until(state);
REQUIRE(*deque.pop_tail() == one);
deque.push_tail<int>(no_op, three);
deque.push_tail<int>(no_op, four);
deque.push_tail<int>(three);
deque.push_tail<int>(four);
REQUIRE(*deque.pop_head() == three);
REQUIRE(*deque.pop_tail() == four);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment