MCPcopy Create free account
hub / github.com/apache/arrow / TEST

Function TEST

cpp/src/arrow/acero/task_util_test.cc:104–177  ·  view source on GitHub ↗

This test simulates one of the current use patterns of the task scheduler. There are a number of groups. The groups are allocated to stages. All groups in a stage execute concurrently. When all groups in that stage finish the next stage is started.

Source from the content-addressed store, hash-verified

102// concurrently. When all groups in that stage finish the next
103// stage is started.
104TEST(TaskScheduler, Stress) {
105#ifndef ARROW_ENABLE_THREADING
106 GTEST_SKIP() << "Test requires threading support";
107#endif
108 constexpr int kNumThreads = 8;
109 constexpr int kNumGroups = 8;
110 constexpr int kGroupsPerStage = 3;
111 constexpr int kTasksPerGroup = 32;
112 constexpr int kNumStages = (kNumGroups % kGroupsPerStage == 0)
113 ? (kNumGroups / kGroupsPerStage)
114 : (kNumGroups / kGroupsPerStage) + 1;
115 constexpr int kTrailingGroups = (kNumGroups % kGroupsPerStage == 0)
116 ? kGroupsPerStage
117 : kNumGroups % kGroupsPerStage;
118
119 ThreadIndexer thread_indexer;
120 int num_threads = std::min(static_cast<int>(thread_indexer.Capacity()), kNumThreads);
121 ASSERT_OK_AND_ASSIGN(std::shared_ptr<ThreadPool> thread_pool,
122 ThreadPool::Make(num_threads));
123
124 std::array<std::atomic<int>, kNumStages - 1> stage_counters;
125 for (int i = 0; i < kNumStages - 1; i++) {
126 stage_counters[i].store(kGroupsPerStage);
127 }
128 std::atomic<int> final_counter(kTrailingGroups);
129 std::mutex mutex;
130 std::condition_variable finish_cv;
131
132 std::vector<int> group_ids;
133 auto scheduler = TaskScheduler::Make();
134
135 std::function<void(std::size_t, int)> start_next_stage = [&](std::size_t thread_id,
136 int stage_index) {
137 int start = stage_index * kGroupsPerStage;
138 int end = std::min(kNumGroups, start + kGroupsPerStage);
139 for (int i = start; i < end; i++) {
140 ASSERT_OK(thread_pool->Spawn([&, i] {
141 std::size_t my_thread_id = thread_indexer();
142 SleepABit();
143 ASSERT_OK(scheduler->StartTaskGroup(my_thread_id, group_ids[i], kTasksPerGroup));
144 }));
145 }
146 };
147
148 for (auto i = 0; i < kNumGroups; i++) {
149 int next_stage = (i / kGroupsPerStage) + 1;
150 TaskScheduler::TaskGroupContinuationImpl finish =
151 MakeFinalContinuation(&final_counter, &mutex, &finish_cv);
152 if (next_stage < kNumStages) {
153 finish =
154 MakeContinuation(&stage_counters[next_stage - 1], start_next_stage, next_stage);
155 }
156 group_ids.push_back(scheduler->RegisterTaskGroup(SlowTaskImpl, finish));
157 }
158 scheduler->RegisterEnd();
159
160 TaskScheduler::AbortContinuationImpl abort = [] { FAIL() << "Unexpected abort"; };
161 TaskScheduler::ScheduleImpl schedule =

Callers

nothing calls this directly

Calls 15

SleepABitFunction · 0.85
MakeFinalContinuationFunction · 0.85
MakeContinuationFunction · 0.85
MakePrimedThreadPoolFunction · 0.85
storeMethod · 0.80
push_backMethod · 0.80
StartSchedulingMethod · 0.80
WaitForIdleMethod · 0.80
IsCancelledMethod · 0.80
ASSERT_OK_AND_ASSIGNFunction · 0.70
MakeFunction · 0.50
InvalidFunction · 0.50

Tested by

no test coverage detected