class ThreadPoolTest : public CommonRuntimeTest { public: static int32_t num_threads;
};
int32_t ThreadPoolTest::num_threads = 4;
// Check that the thread pool actually runs tasks that you assign it.
TEST_F(ThreadPoolTest, CheckRun) {
Thread* self = Thread::Current();
std::unique_ptr<ThreadPool> thread_pool(
ThreadPool::Create("Thread pool test thread pool", num_threads));
AtomicInteger count(0); staticconst int32_t num_tasks = num_threads * 4; for (int32_t i = 0; i < num_tasks; ++i) {
thread_pool->AddTask(self, new CountTask(&count));
}
thread_pool->StartWorkers(self); // Wait for tasks to complete.
thread_pool->Wait(self, true, false); // Make sure that we finished all the work.
EXPECT_EQ(num_tasks, count.load(std::memory_order_seq_cst));
}
TEST_F(ThreadPoolTest, StopStart) {
Thread* self = Thread::Current();
std::unique_ptr<ThreadPool> thread_pool(
ThreadPool::Create("Thread pool test thread pool", num_threads));
AtomicInteger count(0); staticconst int32_t num_tasks = num_threads * 4; for (int32_t i = 0; i < num_tasks; ++i) {
thread_pool->AddTask(self, new CountTask(&count));
}
usleep(200); // Check that no threads started prematurely.
EXPECT_EQ(0, count.load(std::memory_order_seq_cst)); // Signal the threads to start processing tasks.
thread_pool->StartWorkers(self);
usleep(200);
thread_pool->StopWorkers(self);
AtomicInteger bad_count(0);
thread_pool->AddTask(self, new CountTask(&bad_count));
usleep(200); // Ensure that the task added after the workers were stopped doesn't get run.
EXPECT_EQ(0, bad_count.load(std::memory_order_seq_cst)); // Allow tasks to finish up and delete themselves.
thread_pool->StartWorkers(self);
thread_pool->Wait(self, false, false);
}
TEST_F(ThreadPoolTest, StopWait) {
Thread* self = Thread::Current();
std::unique_ptr<ThreadPool> thread_pool(
ThreadPool::Create("Thread pool test thread pool", num_threads));
AtomicInteger count(0); staticconst int32_t num_tasks = num_threads * 100; for (int32_t i = 0; i < num_tasks; ++i) {
thread_pool->AddTask(self, new CountTask(&count));
}
// Signal the threads to start processing tasks.
thread_pool->StartWorkers(self);
usleep(200);
thread_pool->StopWorkers(self);
thread_pool->Wait(self, false, false); // We should not deadlock here.
// Drain the task list. Note: we have to restart here, as no tasks will be finished when // the pool is stopped.
thread_pool->StartWorkers(self);
thread_pool->Wait(self, /* do_work= */ true, false);
}
class TreeTask : public Task { public:
TreeTask(ThreadPool* const thread_pool, AtomicInteger* count, int depth)
: thread_pool_(thread_pool),
count_(count),
depth_(depth) {}
void Run(Thread* self) override { if (depth_ > 1) {
thread_pool_->AddTask(self, new TreeTask(thread_pool_, count_, depth_ - 1));
thread_pool_->AddTask(self, new TreeTask(thread_pool_, count_, depth_ - 1));
} // Increment the counter which keeps track of work completed.
++*count_;
}
// Tests for create_peer functionality.
TEST_F(ThreadPoolTest, PeerTest) {
Thread* self = Thread::Current();
{
std::unique_ptr<ThreadPool> thread_pool(
ThreadPool::Create("Thread pool test thread pool", 1));
thread_pool->AddTask(self, new NoPeerTask());
thread_pool->StartWorkers(self);
thread_pool->Wait(self, false, false);
}
{ // To create peers, the runtime needs to be started.
self->TransitionFromSuspendedToRunnable(); bool started = runtime_->Start();
ASSERT_TRUE(started);
std::unique_ptr<ThreadPool> thread_pool(
ThreadPool::Create("Thread pool test thread pool", 1, true));
thread_pool->AddTask(self, new PeerTask());
thread_pool->StartWorkers(self);
thread_pool->Wait(self, false, false);
}
}
} // namespace art
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.