blob: 4acf7b987fc6f4c13ff08ec24b9ace48bc5fe939 [file] [log] [blame]
Shinichiro Hamaji702befc2016-01-27 17:21:39 +09001// Copyright 2016 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Koichi Shiraishidf8cd052016-09-06 15:05:35 +090015// +build ignore
16
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090017#include "thread_pool.h"
18
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090019#include <condition_variable>
20#include <mutex>
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090021#include <stack>
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090022#include <thread>
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090023#include <vector>
24
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090025#include "affinity.h"
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090026
27class ThreadPoolImpl : public ThreadPool {
28 public:
Dan Willemsen3ce083f2017-10-11 22:17:48 -070029 explicit ThreadPoolImpl(int num_threads) : is_waiting_(false) {
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090030 SetAffinityForMultiThread();
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090031 threads_.reserve(num_threads);
32 for (int i = 0; i < num_threads; i++) {
33 threads_.push_back(thread([this]() { Loop(); }));
34 }
35 }
36
Dan Willemsen3ce083f2017-10-11 22:17:48 -070037 virtual ~ThreadPoolImpl() override {}
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090038
39 virtual void Submit(function<void(void)> task) override {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090040 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090041 tasks_.push(task);
42 cond_.notify_one();
43 }
44
45 virtual void Wait() override {
46 {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090047 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090048 is_waiting_ = true;
49 cond_.notify_all();
50 }
51
52 for (thread& th : threads_) {
53 th.join();
54 }
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090055
56 SetAffinityForSingleThread();
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090057 }
58
59 private:
60 void Loop() {
61 while (true) {
62 function<void(void)> task;
63 {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090064 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090065 if (tasks_.empty()) {
66 if (is_waiting_)
67 return;
68 cond_.wait(lock);
69 }
70
71 if (tasks_.empty())
72 continue;
73
74 task = tasks_.top();
75 tasks_.pop();
76 }
77 task();
78 }
79 }
80
81 vector<thread> threads_;
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090082 mutex mu_;
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090083 condition_variable cond_;
84 stack<function<void(void)>> tasks_;
85 bool is_waiting_;
86};
87
88ThreadPool* NewThreadPool(int num_threads) {
89 return new ThreadPoolImpl(num_threads);
90}