Check TaskGroup behaviour with tasks spawning other tasks
| 187 | |
| 188 | // Check TaskGroup behaviour with tasks spawning other tasks |
| 189 | void TestTasksSpawnTasks(std::shared_ptr<TaskGroup> task_group) { |
| 190 | const int N = 6; |
| 191 | |
| 192 | std::atomic<int> count(0); |
| 193 | // Make a task that recursively spawns itself |
| 194 | std::function<std::function<Status()>(int)> make_task = [&](int i) { |
| 195 | return [&, i]() { |
| 196 | count++; |
| 197 | if (i > 0) { |
| 198 | // Exercise parallelism by spawning two tasks at once and then sleeping |
| 199 | task_group->Append(make_task(i - 1)); |
| 200 | task_group->Append(make_task(i - 1)); |
| 201 | SleepFor(1e-3); |
| 202 | } |
| 203 | return Status::OK(); |
| 204 | }; |
| 205 | }; |
| 206 | |
| 207 | task_group->Append(make_task(N)); |
| 208 | |
| 209 | ASSERT_OK(task_group->Finish()); |
| 210 | ASSERT_TRUE(task_group->ok()); |
| 211 | ASSERT_EQ(count.load(), (1 << (N + 1)) - 1); |
| 212 | } |
| 213 | |
| 214 | // A task that keeps recursing until a barrier is set. |
| 215 | // Using a lambda for this doesn't play well with Thread Sanitizer. |