blob: c504ef5436fcb08f038e1be8ce244e5817ba82b6 [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
15#include "thread_pool.h"
16
17#include <stack>
18#include <vector>
19
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090020#include "affinity.h"
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090021#include "condvar.h"
22#include "mutex.h"
23#include "thread.h"
24
25class ThreadPoolImpl : public ThreadPool {
26 public:
27 explicit ThreadPoolImpl(int num_threads)
28 : is_waiting_(false) {
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090029 SetAffinityForMultiThread();
Shinichiro Hamaji702befc2016-01-27 17:21:39 +090030 threads_.reserve(num_threads);
31 for (int i = 0; i < num_threads; i++) {
32 threads_.push_back(thread([this]() { Loop(); }));
33 }
34 }
35
36 virtual ~ThreadPoolImpl() override {
37 }
38
39 virtual void Submit(function<void(void)> task) override {
Shinichiro Hamajie6438312016-02-16 14:04:05 +090040 UniqueLock<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 Hamajie6438312016-02-16 14:04:05 +090047 UniqueLock<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 Hamajie6438312016-02-16 14:04:05 +090064 UniqueLock<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 Hamajie6438312016-02-16 14:04:05 +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}