1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "perfetto/ext/base/threading/thread_pool.h" 18 #include <mutex> 19 #include <thread> 20 21 namespace perfetto { 22 namespace base { 23 ThreadPool(uint32_t thread_count)24ThreadPool::ThreadPool(uint32_t thread_count) { 25 for (uint32_t i = 0; i < thread_count; ++i) { 26 threads_.emplace_back(std::bind(&ThreadPool::RunThreadLoop, this)); 27 } 28 } 29 ~ThreadPool()30ThreadPool::~ThreadPool() { 31 { 32 std::lock_guard<std::mutex> guard(mutex_); 33 quit_ = true; 34 } 35 thread_waiter_.notify_all(); 36 for (auto& thread : threads_) { 37 thread.join(); 38 } 39 } 40 PostTask(std::function<void ()> fn)41void ThreadPool::PostTask(std::function<void()> fn) { 42 std::lock_guard<std::mutex> guard(mutex_); 43 pending_tasks_.emplace_back(std::move(fn)); 44 if (thread_waiting_count_ == 0) { 45 return; 46 } 47 thread_waiter_.notify_one(); 48 } 49 RunThreadLoop()50void ThreadPool::RunThreadLoop() { 51 for (;;) { 52 std::function<void()> fn; 53 { 54 std::unique_lock<std::mutex> guard(mutex_); 55 if (quit_) { 56 return; 57 } 58 if (pending_tasks_.empty()) { 59 thread_waiting_count_++; 60 thread_waiter_.wait( 61 guard, [this]() { return quit_ || !pending_tasks_.empty(); }); 62 thread_waiting_count_--; 63 continue; 64 } 65 fn = std::move(pending_tasks_.front()); 66 pending_tasks_.pop_front(); 67 } 68 fn(); 69 } 70 } 71 72 } // namespace base 73 } // namespace perfetto 74