完美一版
This commit is contained in:
@@ -261,7 +261,7 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) {
|
||||
Render_Executor executor(Render_Runtime_Config{1});
|
||||
std::atomic_bool entered{false};
|
||||
std::atomic_bool release{false};
|
||||
std::atomic_bool completed{false};
|
||||
std::atomic_int completed{0};
|
||||
auto first_stat = std::make_shared<Frame_Worker_Stat>();
|
||||
ASSERT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
1,
|
||||
@@ -272,29 +272,182 @@ TEST(Renderive_Render_Executor, FrameAdmissionIsBounded) {
|
||||
while (!release.load(std::memory_order_acquire))
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}),
|
||||
{},
|
||||
Task([&]() {
|
||||
completed.store(true, std::memory_order_release);
|
||||
completed.fetch_add(1, std::memory_order_acq_rel);
|
||||
}),
|
||||
first_stat,
|
||||
1,
|
||||
true
|
||||
}));
|
||||
ASSERT_TRUE(wait_until([&]() {
|
||||
return entered.load(std::memory_order_acquire);
|
||||
}));
|
||||
auto second_stat = std::make_shared<Frame_Worker_Stat>();
|
||||
EXPECT_FALSE(executor.try_submit(Render_Executor_Task{
|
||||
EXPECT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
2,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([]() {}),
|
||||
Task([]() {}),
|
||||
{},
|
||||
Task([&]() {
|
||||
completed.fetch_add(1, std::memory_order_acq_rel);
|
||||
}),
|
||||
second_stat,
|
||||
1,
|
||||
true
|
||||
}));
|
||||
auto third_stat = std::make_shared<Frame_Worker_Stat>();
|
||||
EXPECT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
3,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([]() {}),
|
||||
{},
|
||||
Task([&]() {
|
||||
completed.fetch_add(1, std::memory_order_acq_rel);
|
||||
}),
|
||||
third_stat,
|
||||
1,
|
||||
true
|
||||
}));
|
||||
auto duplicate_stat = std::make_shared<Frame_Worker_Stat>();
|
||||
EXPECT_FALSE(executor.try_submit(Render_Executor_Task{
|
||||
2,
|
||||
2,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([]() {}),
|
||||
{},
|
||||
Task([]() {}),
|
||||
duplicate_stat,
|
||||
1,
|
||||
true
|
||||
}));
|
||||
auto overflow_stat = std::make_shared<Frame_Worker_Stat>();
|
||||
EXPECT_FALSE(executor.try_submit(Render_Executor_Task{
|
||||
4,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([]() {}),
|
||||
{},
|
||||
Task([]() {}),
|
||||
overflow_stat,
|
||||
1,
|
||||
true
|
||||
}));
|
||||
release.store(true, std::memory_order_release);
|
||||
ASSERT_TRUE(wait_until([&]() {
|
||||
return completed.load(std::memory_order_acquire) == 3;
|
||||
}));
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
TEST(Renderive_Render_Executor, TaskflowTopologyRunsInFrameOrder) {
|
||||
Render_Executor executor(Render_Runtime_Config{2});
|
||||
std::atomic_int sequence{0};
|
||||
std::atomic_bool completed{false};
|
||||
auto stat = std::make_shared<Frame_Worker_Stat>();
|
||||
|
||||
ASSERT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
1,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task{},
|
||||
[&sequence](tf::Taskflow& taskflow, tf::Task entry, tf::Task exit) {
|
||||
auto prepare = taskflow.emplace([&sequence]() {
|
||||
int expected = 0;
|
||||
sequence.compare_exchange_strong(expected, 1, std::memory_order_acq_rel);
|
||||
});
|
||||
auto draw = taskflow.emplace([&sequence]() {
|
||||
int expected = 1;
|
||||
sequence.compare_exchange_strong(expected, 2, std::memory_order_acq_rel);
|
||||
});
|
||||
auto finalize = taskflow.emplace([&sequence]() {
|
||||
int expected = 2;
|
||||
sequence.compare_exchange_strong(expected, 3, std::memory_order_acq_rel);
|
||||
});
|
||||
entry.precede(prepare);
|
||||
prepare.precede(draw);
|
||||
draw.precede(finalize);
|
||||
finalize.precede(exit);
|
||||
},
|
||||
Task([&completed]() {
|
||||
completed.store(true, std::memory_order_release);
|
||||
}),
|
||||
stat,
|
||||
3,
|
||||
true
|
||||
}));
|
||||
|
||||
ASSERT_TRUE(wait_until([&]() {
|
||||
return completed.load(std::memory_order_acquire);
|
||||
}));
|
||||
EXPECT_EQ(sequence.load(std::memory_order_acquire), 3);
|
||||
EXPECT_EQ(stat->task_count, 3u);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
TEST(Renderive_Render_Executor, QueuedFramesRunRoundRobinByPlot) {
|
||||
Render_Executor executor(Render_Runtime_Config{1});
|
||||
std::atomic_bool first_entered{false};
|
||||
std::atomic_bool release_first{false};
|
||||
std::atomic_int order_index{0};
|
||||
std::array<int, 3> order{};
|
||||
|
||||
ASSERT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
1,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([&]() {
|
||||
first_entered.store(true, std::memory_order_release);
|
||||
while (!release_first.load(std::memory_order_acquire))
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 1;
|
||||
}),
|
||||
{},
|
||||
Task([]() {}),
|
||||
std::make_shared<Frame_Worker_Stat>(),
|
||||
1,
|
||||
true
|
||||
}));
|
||||
ASSERT_TRUE(wait_until([&]() {
|
||||
return first_entered.load(std::memory_order_acquire);
|
||||
}));
|
||||
|
||||
ASSERT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
2,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([&]() {
|
||||
order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 2;
|
||||
}),
|
||||
{},
|
||||
Task([]() {}),
|
||||
std::make_shared<Frame_Worker_Stat>(),
|
||||
1,
|
||||
true
|
||||
}));
|
||||
ASSERT_TRUE(executor.try_submit(Render_Executor_Task{
|
||||
3,
|
||||
1,
|
||||
Render_Task_Kind::Frame,
|
||||
Task([&]() {
|
||||
order[order_index.fetch_add(1, std::memory_order_acq_rel)] = 3;
|
||||
}),
|
||||
{},
|
||||
Task([]() {}),
|
||||
std::make_shared<Frame_Worker_Stat>(),
|
||||
1,
|
||||
true
|
||||
}));
|
||||
|
||||
release_first.store(true, std::memory_order_release);
|
||||
ASSERT_TRUE(wait_until([&]() {
|
||||
return order_index.load(std::memory_order_acquire) == 3;
|
||||
}));
|
||||
EXPECT_EQ(order[0], 1);
|
||||
EXPECT_EQ(order[1], 2);
|
||||
EXPECT_EQ(order[2], 3);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user