| 196 | }; |
| 197 | |
| 198 | TEST_F(FunctionLibraryRuntimeTest, DefaultThreadpool) { |
| 199 | using test::function::blocking_op_state; |
| 200 | using test::function::BlockingOpState; |
| 201 | |
| 202 | thread::ThreadPool* tp = new thread::ThreadPool(Env::Default(), "FLRTest", 1); |
| 203 | Init({test::function::BlockingOpFn(), test::function::XTimesTwo()}, tp); |
| 204 | |
| 205 | auto x = test::AsScalar<float>(1.3); |
| 206 | Tensor y; |
| 207 | blocking_op_state = new BlockingOpState(); |
| 208 | |
| 209 | thread::ThreadPool* tp1 = new thread::ThreadPool(Env::Default(), "tp1", 5); |
| 210 | bool finished_running = false; |
| 211 | tp1->Schedule([&x, &y, &finished_running, this]() { |
| 212 | TF_CHECK_OK(InstantiateAndRun(flr0_, "BlockingOpFn", {}, {x}, {&y}, |
| 213 | false /* add_runner */)); |
| 214 | finished_running = true; |
| 215 | }); |
| 216 | |
| 217 | // InstantiateAndRun shouldn't finish because BlockingOpFn should be blocked. |
| 218 | EXPECT_FALSE(finished_running); |
| 219 | |
| 220 | FunctionLibraryRuntime::Handle h; |
| 221 | TF_CHECK_OK(Instantiate(flr0_, "XTimesTwo", {{"T", DT_FLOAT}}, &h)); |
| 222 | |
| 223 | auto x1 = test::AsTensor<float>({1, 2, 3, 4}); |
| 224 | std::atomic<int32> num_done(0); |
| 225 | FunctionLibraryRuntime::Options opts; |
| 226 | for (int i = 0; i < 4; ++i) { |
| 227 | tp1->Schedule([&h, &x1, &opts, &num_done, this]() { |
| 228 | Tensor y1; |
| 229 | TF_CHECK_OK(Run(flr0_, h, opts, {x1}, {&y1}, false /* add_runner */)); |
| 230 | num_done.fetch_add(1); |
| 231 | }); |
| 232 | } |
| 233 | // All the 4 Run() calls should be blocked because the runner is occupied. |
| 234 | EXPECT_EQ(0, num_done.load()); |
| 235 | |
| 236 | blocking_op_state->AwaitState(1); |
| 237 | blocking_op_state->MoveToState(1, 2); |
| 238 | // Now the runner should be unblocked and all the other Run() calls should |
| 239 | // proceed. |
| 240 | blocking_op_state->AwaitState(3); |
| 241 | blocking_op_state->MoveToState(3, 0); |
| 242 | delete tp1; |
| 243 | EXPECT_TRUE(finished_running); |
| 244 | EXPECT_EQ(4, num_done.load()); |
| 245 | |
| 246 | delete blocking_op_state; |
| 247 | blocking_op_state = nullptr; |
| 248 | delete tp; |
| 249 | } |
| 250 | |
| 251 | } // namespace |
| 252 | } // namespace tensorflow |
nothing calls this directly
no test coverage detected