blob: b2429cbc91cb0b300d93419c1c2bdb5f2820070a [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:
29 explicit ThreadPoolImpl(int num_threads)
30 : is_waiting_(false) {
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090031 SetAffinityForMultiThread();
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090032 threads_.reserve(num_threads);
33 for (int i = 0; i < num_threads; i++) {
34 threads_.push_back(thread([this]() { Loop(); }));
35 }
36 }
37
38 virtual ~ThreadPoolImpl() override {
39 }
40
41 virtual void Submit(function<void(void)> task) override {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090042 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090043 tasks_.push(task);
44 cond_.notify_one();
45 }
46
47 virtual void Wait() override {
48 {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090049 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090050 is_waiting_ = true;
51 cond_.notify_all();
52 }
53
54 for (thread& th : threads_) {
55 th.join();
56 }
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090057
58 SetAffinityForSingleThread();
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090059 }
60
61 private:
62 void Loop() {
63 while (true) {
64 function<void(void)> task;
65 {
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090066 unique_lock<mutex> lock(mu_);
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090067 if (tasks_.empty()) {
68 if (is_waiting_)
69 return;
70 cond_.wait(lock);
71 }
72
73 if (tasks_.empty())
74 continue;
75
76 task = tasks_.top();
77 tasks_.pop();
78 }
79 task();
80 }
81 }
82
83 vector<thread> threads_;
Shinichiro Hamaji8380fb82016-02-26 16:51:50 +090084 mutex mu_;
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090085 condition_variable cond_;
86 stack<function<void(void)>> tasks_;
87 bool is_waiting_;
88};
89
90ThreadPool* NewThreadPool(int num_threads) {
91 return new ThreadPoolImpl(num_threads);
92}