proxygen
GlobalThreadPoolList.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
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 
18 
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include <folly/CppAttributes.h>
24 #include <folly/Indestructible.h>
25 #include <folly/Synchronized.h>
26 #include <folly/ThreadLocal.h>
27 
28 namespace folly {
29 
30 namespace {
31 
32 class ThreadListHook {
33  public:
34  ThreadListHook(ThreadPoolListHook* poolId, std::thread::id threadId);
35  ~ThreadListHook();
36 
37  private:
38  ThreadListHook() {}
39  ThreadPoolListHook* poolId_;
40  std::thread::id threadId_;
41 };
42 
43 class GlobalThreadPoolListImpl {
44  public:
45  GlobalThreadPoolListImpl() {}
46 
47  void registerThreadPool(ThreadPoolListHook* threadPoolId, std::string name);
48 
49  void unregisterThreadPool(ThreadPoolListHook* threadPoolId);
50 
51  void registerThreadPoolThread(
52  ThreadPoolListHook* threadPoolId,
53  std::thread::id threadId);
54 
55  void unregisterThreadPoolThread(
56  ThreadPoolListHook* threadPoolId,
57  std::thread::id threadId);
58 
59  private:
60  struct PoolInfo {
61  ThreadPoolListHook* addr;
63  std::vector<std::thread::id> threads;
64  };
65 
66  struct Pools {
67  // Just a vector since ease of access from gdb is the most important
68  // property
69  std::vector<PoolInfo> poolsInfo_;
70 
71  std::vector<std::thread::id>* FOLLY_NULLABLE
72  getThreadVector(void* threadPoolId) {
73  for (auto& elem : vector()) {
74  if (elem.addr == threadPoolId) {
75  return &elem.threads;
76  }
77  }
78 
79  return nullptr;
80  }
81 
82  std::vector<PoolInfo>& vector() {
83  return poolsInfo_;
84  }
85  };
86 
87  Pools pools_;
88 };
89 
90 class GlobalThreadPoolList {
91  public:
92  GlobalThreadPoolList() {}
93 
94  static GlobalThreadPoolList& instance();
95 
96  void registerThreadPool(ThreadPoolListHook* threadPoolId, std::string name);
97 
98  void unregisterThreadPool(ThreadPoolListHook* threadPoolId);
99 
100  void registerThreadPoolThread(
101  ThreadPoolListHook* threadPoolId,
102  std::thread::id threadId);
103 
104  void unregisterThreadPoolThread(
105  ThreadPoolListHook* threadPoolId,
106  std::thread::id threadId);
107 
108  GlobalThreadPoolList(GlobalThreadPoolList const&) = delete;
109  void operator=(GlobalThreadPoolList const&) = delete;
110 
111  private:
114 };
115 
116 } // namespace
117 
118 GlobalThreadPoolList& GlobalThreadPoolList::instance() {
120  return *ret;
121 }
122 
123 void GlobalThreadPoolList::registerThreadPool(
124  ThreadPoolListHook* threadPoolId,
125  std::string name) {
126  globalListImpl_->registerThreadPool(threadPoolId, name);
127 }
128 
129 void GlobalThreadPoolList::unregisterThreadPool(
130  ThreadPoolListHook* threadPoolId) {
131  globalListImpl_->unregisterThreadPool(threadPoolId);
132 }
133 
134 void GlobalThreadPoolList::registerThreadPoolThread(
135  ThreadPoolListHook* threadPoolId,
136  std::thread::id threadId) {
137  DCHECK(!threadHook_);
138  threadHook_.reset(make_unique<ThreadListHook>(threadPoolId, threadId));
139 
140  globalListImpl_->registerThreadPoolThread(threadPoolId, threadId);
141 }
142 
143 void GlobalThreadPoolList::unregisterThreadPoolThread(
144  ThreadPoolListHook* threadPoolId,
145  std::thread::id threadId) {
146  (void)threadPoolId;
147  (void)threadId;
148  globalListImpl_->unregisterThreadPoolThread(threadPoolId, threadId);
149 }
150 
151 void GlobalThreadPoolListImpl::registerThreadPool(
152  ThreadPoolListHook* threadPoolId,
153  std::string name) {
154  PoolInfo info;
155  info.name = name;
156  info.addr = threadPoolId;
157  pools_.vector().push_back(info);
158 }
159 
160 void GlobalThreadPoolListImpl::unregisterThreadPool(
161  ThreadPoolListHook* threadPoolId) {
162  auto& vector = pools_.vector();
163  vector.erase(
164  std::remove_if(
165  vector.begin(),
166  vector.end(),
167  [=](PoolInfo& i) { return i.addr == threadPoolId; }),
168  vector.end());
169 }
170 
171 void GlobalThreadPoolListImpl::registerThreadPoolThread(
172  ThreadPoolListHook* threadPoolId,
173  std::thread::id threadId) {
174  auto vec = pools_.getThreadVector(threadPoolId);
175  if (vec == nullptr) {
176  return;
177  }
178 
179  vec->push_back(threadId);
180 }
181 
182 void GlobalThreadPoolListImpl::unregisterThreadPoolThread(
183  ThreadPoolListHook* threadPoolId,
184  std::thread::id threadId) {
185  auto vec = pools_.getThreadVector(threadPoolId);
186  if (vec == nullptr) {
187  return;
188  }
189 
190  vec->erase(std::remove(vec->begin(), vec->end(), threadId), vec->end());
191 }
192 
193 ThreadListHook::ThreadListHook(
194  ThreadPoolListHook* poolId,
195  std::thread::id threadId) {
196  poolId_ = poolId;
197  threadId_ = threadId;
198 }
199 
200 ThreadListHook::~ThreadListHook() {
201  GlobalThreadPoolList::instance().unregisterThreadPoolThread(
202  poolId_, threadId_);
203 }
204 
206  GlobalThreadPoolList::instance().registerThreadPool(this, name);
207 }
208 
210  GlobalThreadPoolList::instance().unregisterThreadPool(this);
211 }
212 
214  GlobalThreadPoolList::instance().registerThreadPoolThread(
215  this, std::this_thread::get_id());
216 }
217 
218 } // namespace folly
def info()
Definition: deadlock.py:447
folly::Synchronized< GlobalThreadPoolListImpl > globalListImpl_
Pools pools_
std::thread::id threadId_
#define FOLLY_NULLABLE
ThreadPoolListHook * poolId_
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::string name
std::vector< std::thread::id > threads
Definition: Traits.h:588
const char * string
Definition: Conv.cpp:212
folly::ThreadLocalPtr< ThreadListHook > threadHook_
ThreadPoolListHook * addr
std::vector< PoolInfo > poolsInfo_