add missing include to ThreadId.h
[folly.git] / folly / test / CacheLocalityTest.cpp
1 /*
2  * Copyright 2017 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
17 #include <folly/detail/CacheLocality.h>
18
19 #include <folly/portability/GTest.h>
20
21 #include <memory>
22 #include <thread>
23 #include <type_traits>
24 #include <unordered_map>
25 #include <glog/logging.h>
26
27 using namespace folly::detail;
28
29 /// This is the relevant nodes from a production box's sysfs tree.  If you
30 /// think this map is ugly you should see the version of this test that
31 /// used a real directory tree.  To reduce the chance of testing error
32 /// I haven't tried to remove the common prefix
33 static std::unordered_map<std::string, std::string> fakeSysfsTree = {
34     {"/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list", "0,17"},
35     {"/sys/devices/system/cpu/cpu0/cache/index0/type", "Data"},
36     {"/sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_list", "0,17"},
37     {"/sys/devices/system/cpu/cpu0/cache/index1/type", "Instruction"},
38     {"/sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_list", "0,17"},
39     {"/sys/devices/system/cpu/cpu0/cache/index2/type", "Unified"},
40     {"/sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list", "0-8,17-23"},
41     {"/sys/devices/system/cpu/cpu0/cache/index3/type", "Unified"},
42     {"/sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_list", "1,18"},
43     {"/sys/devices/system/cpu/cpu1/cache/index0/type", "Data"},
44     {"/sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_list", "1,18"},
45     {"/sys/devices/system/cpu/cpu1/cache/index1/type", "Instruction"},
46     {"/sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_list", "1,18"},
47     {"/sys/devices/system/cpu/cpu1/cache/index2/type", "Unified"},
48     {"/sys/devices/system/cpu/cpu1/cache/index3/shared_cpu_list", "0-8,17-23"},
49     {"/sys/devices/system/cpu/cpu1/cache/index3/type", "Unified"},
50     {"/sys/devices/system/cpu/cpu2/cache/index0/shared_cpu_list", "2,19"},
51     {"/sys/devices/system/cpu/cpu2/cache/index0/type", "Data"},
52     {"/sys/devices/system/cpu/cpu2/cache/index1/shared_cpu_list", "2,19"},
53     {"/sys/devices/system/cpu/cpu2/cache/index1/type", "Instruction"},
54     {"/sys/devices/system/cpu/cpu2/cache/index2/shared_cpu_list", "2,19"},
55     {"/sys/devices/system/cpu/cpu2/cache/index2/type", "Unified"},
56     {"/sys/devices/system/cpu/cpu2/cache/index3/shared_cpu_list", "0-8,17-23"},
57     {"/sys/devices/system/cpu/cpu2/cache/index3/type", "Unified"},
58     {"/sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_list", "3,20"},
59     {"/sys/devices/system/cpu/cpu3/cache/index0/type", "Data"},
60     {"/sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_list", "3,20"},
61     {"/sys/devices/system/cpu/cpu3/cache/index1/type", "Instruction"},
62     {"/sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_list", "3,20"},
63     {"/sys/devices/system/cpu/cpu3/cache/index2/type", "Unified"},
64     {"/sys/devices/system/cpu/cpu3/cache/index3/shared_cpu_list", "0-8,17-23"},
65     {"/sys/devices/system/cpu/cpu3/cache/index3/type", "Unified"},
66     {"/sys/devices/system/cpu/cpu4/cache/index0/shared_cpu_list", "4,21"},
67     {"/sys/devices/system/cpu/cpu4/cache/index0/type", "Data"},
68     {"/sys/devices/system/cpu/cpu4/cache/index1/shared_cpu_list", "4,21"},
69     {"/sys/devices/system/cpu/cpu4/cache/index1/type", "Instruction"},
70     {"/sys/devices/system/cpu/cpu4/cache/index2/shared_cpu_list", "4,21"},
71     {"/sys/devices/system/cpu/cpu4/cache/index2/type", "Unified"},
72     {"/sys/devices/system/cpu/cpu4/cache/index3/shared_cpu_list", "0-8,17-23"},
73     {"/sys/devices/system/cpu/cpu4/cache/index3/type", "Unified"},
74     {"/sys/devices/system/cpu/cpu5/cache/index0/shared_cpu_list", "5-6"},
75     {"/sys/devices/system/cpu/cpu5/cache/index0/type", "Data"},
76     {"/sys/devices/system/cpu/cpu5/cache/index1/shared_cpu_list", "5-6"},
77     {"/sys/devices/system/cpu/cpu5/cache/index1/type", "Instruction"},
78     {"/sys/devices/system/cpu/cpu5/cache/index2/shared_cpu_list", "5-6"},
79     {"/sys/devices/system/cpu/cpu5/cache/index2/type", "Unified"},
80     {"/sys/devices/system/cpu/cpu5/cache/index3/shared_cpu_list", "0-8,17-23"},
81     {"/sys/devices/system/cpu/cpu5/cache/index3/type", "Unified"},
82     {"/sys/devices/system/cpu/cpu6/cache/index0/shared_cpu_list", "5-6"},
83     {"/sys/devices/system/cpu/cpu6/cache/index0/type", "Data"},
84     {"/sys/devices/system/cpu/cpu6/cache/index1/shared_cpu_list", "5-6"},
85     {"/sys/devices/system/cpu/cpu6/cache/index1/type", "Instruction"},
86     {"/sys/devices/system/cpu/cpu6/cache/index2/shared_cpu_list", "5-6"},
87     {"/sys/devices/system/cpu/cpu6/cache/index2/type", "Unified"},
88     {"/sys/devices/system/cpu/cpu6/cache/index3/shared_cpu_list", "0-8,17-23"},
89     {"/sys/devices/system/cpu/cpu6/cache/index3/type", "Unified"},
90     {"/sys/devices/system/cpu/cpu7/cache/index0/shared_cpu_list", "7,22"},
91     {"/sys/devices/system/cpu/cpu7/cache/index0/type", "Data"},
92     {"/sys/devices/system/cpu/cpu7/cache/index1/shared_cpu_list", "7,22"},
93     {"/sys/devices/system/cpu/cpu7/cache/index1/type", "Instruction"},
94     {"/sys/devices/system/cpu/cpu7/cache/index2/shared_cpu_list", "7,22"},
95     {"/sys/devices/system/cpu/cpu7/cache/index2/type", "Unified"},
96     {"/sys/devices/system/cpu/cpu7/cache/index3/shared_cpu_list", "0-8,17-23"},
97     {"/sys/devices/system/cpu/cpu7/cache/index3/type", "Unified"},
98     {"/sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list", "8,23"},
99     {"/sys/devices/system/cpu/cpu8/cache/index0/type", "Data"},
100     {"/sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list", "8,23"},
101     {"/sys/devices/system/cpu/cpu8/cache/index1/type", "Instruction"},
102     {"/sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list", "8,23"},
103     {"/sys/devices/system/cpu/cpu8/cache/index2/type", "Unified"},
104     {"/sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list", "0-8,17-23"},
105     {"/sys/devices/system/cpu/cpu8/cache/index3/type", "Unified"},
106     {"/sys/devices/system/cpu/cpu9/cache/index0/shared_cpu_list", "9,24"},
107     {"/sys/devices/system/cpu/cpu9/cache/index0/type", "Data"},
108     {"/sys/devices/system/cpu/cpu9/cache/index1/shared_cpu_list", "9,24"},
109     {"/sys/devices/system/cpu/cpu9/cache/index1/type", "Instruction"},
110     {"/sys/devices/system/cpu/cpu9/cache/index2/shared_cpu_list", "9,24"},
111     {"/sys/devices/system/cpu/cpu9/cache/index2/type", "Unified"},
112     {"/sys/devices/system/cpu/cpu9/cache/index3/shared_cpu_list", "9-16,24-31"},
113     {"/sys/devices/system/cpu/cpu9/cache/index3/type", "Unified"},
114     {"/sys/devices/system/cpu/cpu10/cache/index0/shared_cpu_list", "10,25"},
115     {"/sys/devices/system/cpu/cpu10/cache/index0/type", "Data"},
116     {"/sys/devices/system/cpu/cpu10/cache/index1/shared_cpu_list", "10,25"},
117     {"/sys/devices/system/cpu/cpu10/cache/index1/type", "Instruction"},
118     {"/sys/devices/system/cpu/cpu10/cache/index2/shared_cpu_list", "10,25"},
119     {"/sys/devices/system/cpu/cpu10/cache/index2/type", "Unified"},
120     {"/sys/devices/system/cpu/cpu10/cache/index3/shared_cpu_list",
121      "9-16,24-31"},
122     {"/sys/devices/system/cpu/cpu10/cache/index3/type", "Unified"},
123     {"/sys/devices/system/cpu/cpu11/cache/index0/shared_cpu_list", "11,26"},
124     {"/sys/devices/system/cpu/cpu11/cache/index0/type", "Data"},
125     {"/sys/devices/system/cpu/cpu11/cache/index1/shared_cpu_list", "11,26"},
126     {"/sys/devices/system/cpu/cpu11/cache/index1/type", "Instruction"},
127     {"/sys/devices/system/cpu/cpu11/cache/index2/shared_cpu_list", "11,26"},
128     {"/sys/devices/system/cpu/cpu11/cache/index2/type", "Unified"},
129     {"/sys/devices/system/cpu/cpu11/cache/index3/shared_cpu_list",
130      "9-16,24-31"},
131     {"/sys/devices/system/cpu/cpu11/cache/index3/type", "Unified"},
132     {"/sys/devices/system/cpu/cpu12/cache/index0/shared_cpu_list", "12,27"},
133     {"/sys/devices/system/cpu/cpu12/cache/index0/type", "Data"},
134     {"/sys/devices/system/cpu/cpu12/cache/index1/shared_cpu_list", "12,27"},
135     {"/sys/devices/system/cpu/cpu12/cache/index1/type", "Instruction"},
136     {"/sys/devices/system/cpu/cpu12/cache/index2/shared_cpu_list", "12,27"},
137     {"/sys/devices/system/cpu/cpu12/cache/index2/type", "Unified"},
138     {"/sys/devices/system/cpu/cpu12/cache/index3/shared_cpu_list",
139      "9-16,24-31"},
140     {"/sys/devices/system/cpu/cpu12/cache/index3/type", "Unified"},
141     {"/sys/devices/system/cpu/cpu13/cache/index0/shared_cpu_list", "13,28"},
142     {"/sys/devices/system/cpu/cpu13/cache/index0/type", "Data"},
143     {"/sys/devices/system/cpu/cpu13/cache/index1/shared_cpu_list", "13,28"},
144     {"/sys/devices/system/cpu/cpu13/cache/index1/type", "Instruction"},
145     {"/sys/devices/system/cpu/cpu13/cache/index2/shared_cpu_list", "13,28"},
146     {"/sys/devices/system/cpu/cpu13/cache/index2/type", "Unified"},
147     {"/sys/devices/system/cpu/cpu13/cache/index3/shared_cpu_list",
148      "9-16,24-31"},
149     {"/sys/devices/system/cpu/cpu13/cache/index3/type", "Unified"},
150     {"/sys/devices/system/cpu/cpu14/cache/index0/shared_cpu_list", "14,29"},
151     {"/sys/devices/system/cpu/cpu14/cache/index0/type", "Data"},
152     {"/sys/devices/system/cpu/cpu14/cache/index1/shared_cpu_list", "14,29"},
153     {"/sys/devices/system/cpu/cpu14/cache/index1/type", "Instruction"},
154     {"/sys/devices/system/cpu/cpu14/cache/index2/shared_cpu_list", "14,29"},
155     {"/sys/devices/system/cpu/cpu14/cache/index2/type", "Unified"},
156     {"/sys/devices/system/cpu/cpu14/cache/index3/shared_cpu_list",
157      "9-16,24-31"},
158     {"/sys/devices/system/cpu/cpu14/cache/index3/type", "Unified"},
159     {"/sys/devices/system/cpu/cpu15/cache/index0/shared_cpu_list", "15,30"},
160     {"/sys/devices/system/cpu/cpu15/cache/index0/type", "Data"},
161     {"/sys/devices/system/cpu/cpu15/cache/index1/shared_cpu_list", "15,30"},
162     {"/sys/devices/system/cpu/cpu15/cache/index1/type", "Instruction"},
163     {"/sys/devices/system/cpu/cpu15/cache/index2/shared_cpu_list", "15,30"},
164     {"/sys/devices/system/cpu/cpu15/cache/index2/type", "Unified"},
165     {"/sys/devices/system/cpu/cpu15/cache/index3/shared_cpu_list",
166      "9-16,24-31"},
167     {"/sys/devices/system/cpu/cpu15/cache/index3/type", "Unified"},
168     {"/sys/devices/system/cpu/cpu16/cache/index0/shared_cpu_list", "16,31"},
169     {"/sys/devices/system/cpu/cpu16/cache/index0/type", "Data"},
170     {"/sys/devices/system/cpu/cpu16/cache/index1/shared_cpu_list", "16,31"},
171     {"/sys/devices/system/cpu/cpu16/cache/index1/type", "Instruction"},
172     {"/sys/devices/system/cpu/cpu16/cache/index2/shared_cpu_list", "16,31"},
173     {"/sys/devices/system/cpu/cpu16/cache/index2/type", "Unified"},
174     {"/sys/devices/system/cpu/cpu16/cache/index3/shared_cpu_list",
175      "9-16,24-31"},
176     {"/sys/devices/system/cpu/cpu16/cache/index3/type", "Unified"},
177     {"/sys/devices/system/cpu/cpu17/cache/index0/shared_cpu_list", "0,17"},
178     {"/sys/devices/system/cpu/cpu17/cache/index0/type", "Data"},
179     {"/sys/devices/system/cpu/cpu17/cache/index1/shared_cpu_list", "0,17"},
180     {"/sys/devices/system/cpu/cpu17/cache/index1/type", "Instruction"},
181     {"/sys/devices/system/cpu/cpu17/cache/index2/shared_cpu_list", "0,17"},
182     {"/sys/devices/system/cpu/cpu17/cache/index2/type", "Unified"},
183     {"/sys/devices/system/cpu/cpu17/cache/index3/shared_cpu_list", "0-8,17-23"},
184     {"/sys/devices/system/cpu/cpu17/cache/index3/type", "Unified"},
185     {"/sys/devices/system/cpu/cpu18/cache/index0/shared_cpu_list", "1,18"},
186     {"/sys/devices/system/cpu/cpu18/cache/index0/type", "Data"},
187     {"/sys/devices/system/cpu/cpu18/cache/index1/shared_cpu_list", "1,18"},
188     {"/sys/devices/system/cpu/cpu18/cache/index1/type", "Instruction"},
189     {"/sys/devices/system/cpu/cpu18/cache/index2/shared_cpu_list", "1,18"},
190     {"/sys/devices/system/cpu/cpu18/cache/index2/type", "Unified"},
191     {"/sys/devices/system/cpu/cpu18/cache/index3/shared_cpu_list", "0-8,17-23"},
192     {"/sys/devices/system/cpu/cpu18/cache/index3/type", "Unified"},
193     {"/sys/devices/system/cpu/cpu19/cache/index0/shared_cpu_list", "2,19"},
194     {"/sys/devices/system/cpu/cpu19/cache/index0/type", "Data"},
195     {"/sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_list", "2,19"},
196     {"/sys/devices/system/cpu/cpu19/cache/index1/type", "Instruction"},
197     {"/sys/devices/system/cpu/cpu19/cache/index2/shared_cpu_list", "2,19"},
198     {"/sys/devices/system/cpu/cpu19/cache/index2/type", "Unified"},
199     {"/sys/devices/system/cpu/cpu19/cache/index3/shared_cpu_list", "0-8,17-23"},
200     {"/sys/devices/system/cpu/cpu19/cache/index3/type", "Unified"},
201     {"/sys/devices/system/cpu/cpu20/cache/index0/shared_cpu_list", "3,20"},
202     {"/sys/devices/system/cpu/cpu20/cache/index0/type", "Data"},
203     {"/sys/devices/system/cpu/cpu20/cache/index1/shared_cpu_list", "3,20"},
204     {"/sys/devices/system/cpu/cpu20/cache/index1/type", "Instruction"},
205     {"/sys/devices/system/cpu/cpu20/cache/index2/shared_cpu_list", "3,20"},
206     {"/sys/devices/system/cpu/cpu20/cache/index2/type", "Unified"},
207     {"/sys/devices/system/cpu/cpu20/cache/index3/shared_cpu_list", "0-8,17-23"},
208     {"/sys/devices/system/cpu/cpu20/cache/index3/type", "Unified"},
209     {"/sys/devices/system/cpu/cpu21/cache/index0/shared_cpu_list", "4,21"},
210     {"/sys/devices/system/cpu/cpu21/cache/index0/type", "Data"},
211     {"/sys/devices/system/cpu/cpu21/cache/index1/shared_cpu_list", "4,21"},
212     {"/sys/devices/system/cpu/cpu21/cache/index1/type", "Instruction"},
213     {"/sys/devices/system/cpu/cpu21/cache/index2/shared_cpu_list", "4,21"},
214     {"/sys/devices/system/cpu/cpu21/cache/index2/type", "Unified"},
215     {"/sys/devices/system/cpu/cpu21/cache/index3/shared_cpu_list", "0-8,17-23"},
216     {"/sys/devices/system/cpu/cpu21/cache/index3/type", "Unified"},
217     {"/sys/devices/system/cpu/cpu22/cache/index0/shared_cpu_list", "7,22"},
218     {"/sys/devices/system/cpu/cpu22/cache/index0/type", "Data"},
219     {"/sys/devices/system/cpu/cpu22/cache/index1/shared_cpu_list", "7,22"},
220     {"/sys/devices/system/cpu/cpu22/cache/index1/type", "Instruction"},
221     {"/sys/devices/system/cpu/cpu22/cache/index2/shared_cpu_list", "7,22"},
222     {"/sys/devices/system/cpu/cpu22/cache/index2/type", "Unified"},
223     {"/sys/devices/system/cpu/cpu22/cache/index3/shared_cpu_list", "0-8,17-23"},
224     {"/sys/devices/system/cpu/cpu22/cache/index3/type", "Unified"},
225     {"/sys/devices/system/cpu/cpu23/cache/index0/shared_cpu_list", "8,23"},
226     {"/sys/devices/system/cpu/cpu23/cache/index0/type", "Data"},
227     {"/sys/devices/system/cpu/cpu23/cache/index1/shared_cpu_list", "8,23"},
228     {"/sys/devices/system/cpu/cpu23/cache/index1/type", "Instruction"},
229     {"/sys/devices/system/cpu/cpu23/cache/index2/shared_cpu_list", "8,23"},
230     {"/sys/devices/system/cpu/cpu23/cache/index2/type", "Unified"},
231     {"/sys/devices/system/cpu/cpu23/cache/index3/shared_cpu_list", "0-8,17-23"},
232     {"/sys/devices/system/cpu/cpu23/cache/index3/type", "Unified"},
233     {"/sys/devices/system/cpu/cpu24/cache/index0/shared_cpu_list", "9,24"},
234     {"/sys/devices/system/cpu/cpu24/cache/index0/type", "Data"},
235     {"/sys/devices/system/cpu/cpu24/cache/index1/shared_cpu_list", "9,24"},
236     {"/sys/devices/system/cpu/cpu24/cache/index1/type", "Instruction"},
237     {"/sys/devices/system/cpu/cpu24/cache/index2/shared_cpu_list", "9,24"},
238     {"/sys/devices/system/cpu/cpu24/cache/index2/type", "Unified"},
239     {"/sys/devices/system/cpu/cpu24/cache/index3/shared_cpu_list",
240      "9-16,24-31"},
241     {"/sys/devices/system/cpu/cpu24/cache/index3/type", "Unified"},
242     {"/sys/devices/system/cpu/cpu25/cache/index0/shared_cpu_list", "10,25"},
243     {"/sys/devices/system/cpu/cpu25/cache/index0/type", "Data"},
244     {"/sys/devices/system/cpu/cpu25/cache/index1/shared_cpu_list", "10,25"},
245     {"/sys/devices/system/cpu/cpu25/cache/index1/type", "Instruction"},
246     {"/sys/devices/system/cpu/cpu25/cache/index2/shared_cpu_list", "10,25"},
247     {"/sys/devices/system/cpu/cpu25/cache/index2/type", "Unified"},
248     {"/sys/devices/system/cpu/cpu25/cache/index3/shared_cpu_list",
249      "9-16,24-31"},
250     {"/sys/devices/system/cpu/cpu25/cache/index3/type", "Unified"},
251     {"/sys/devices/system/cpu/cpu26/cache/index0/shared_cpu_list", "11,26"},
252     {"/sys/devices/system/cpu/cpu26/cache/index0/type", "Data"},
253     {"/sys/devices/system/cpu/cpu26/cache/index1/shared_cpu_list", "11,26"},
254     {"/sys/devices/system/cpu/cpu26/cache/index1/type", "Instruction"},
255     {"/sys/devices/system/cpu/cpu26/cache/index2/shared_cpu_list", "11,26"},
256     {"/sys/devices/system/cpu/cpu26/cache/index2/type", "Unified"},
257     {"/sys/devices/system/cpu/cpu26/cache/index3/shared_cpu_list",
258      "9-16,24-31"},
259     {"/sys/devices/system/cpu/cpu26/cache/index3/type", "Unified"},
260     {"/sys/devices/system/cpu/cpu27/cache/index0/shared_cpu_list", "12,27"},
261     {"/sys/devices/system/cpu/cpu27/cache/index0/type", "Data"},
262     {"/sys/devices/system/cpu/cpu27/cache/index1/shared_cpu_list", "12,27"},
263     {"/sys/devices/system/cpu/cpu27/cache/index1/type", "Instruction"},
264     {"/sys/devices/system/cpu/cpu27/cache/index2/shared_cpu_list", "12,27"},
265     {"/sys/devices/system/cpu/cpu27/cache/index2/type", "Unified"},
266     {"/sys/devices/system/cpu/cpu27/cache/index3/shared_cpu_list",
267      "9-16,24-31"},
268     {"/sys/devices/system/cpu/cpu27/cache/index3/type", "Unified"},
269     {"/sys/devices/system/cpu/cpu28/cache/index0/shared_cpu_list", "13,28"},
270     {"/sys/devices/system/cpu/cpu28/cache/index0/type", "Data"},
271     {"/sys/devices/system/cpu/cpu28/cache/index1/shared_cpu_list", "13,28"},
272     {"/sys/devices/system/cpu/cpu28/cache/index1/type", "Instruction"},
273     {"/sys/devices/system/cpu/cpu28/cache/index2/shared_cpu_list", "13,28"},
274     {"/sys/devices/system/cpu/cpu28/cache/index2/type", "Unified"},
275     {"/sys/devices/system/cpu/cpu28/cache/index3/shared_cpu_list",
276      "9-16,24-31"},
277     {"/sys/devices/system/cpu/cpu28/cache/index3/type", "Unified"},
278     {"/sys/devices/system/cpu/cpu29/cache/index0/shared_cpu_list", "14,29"},
279     {"/sys/devices/system/cpu/cpu29/cache/index0/type", "Data"},
280     {"/sys/devices/system/cpu/cpu29/cache/index1/shared_cpu_list", "14,29"},
281     {"/sys/devices/system/cpu/cpu29/cache/index1/type", "Instruction"},
282     {"/sys/devices/system/cpu/cpu29/cache/index2/shared_cpu_list", "14,29"},
283     {"/sys/devices/system/cpu/cpu29/cache/index2/type", "Unified"},
284     {"/sys/devices/system/cpu/cpu29/cache/index3/shared_cpu_list",
285      "9-16,24-31"},
286     {"/sys/devices/system/cpu/cpu29/cache/index3/type", "Unified"},
287     {"/sys/devices/system/cpu/cpu30/cache/index0/shared_cpu_list", "15,30"},
288     {"/sys/devices/system/cpu/cpu30/cache/index0/type", "Data"},
289     {"/sys/devices/system/cpu/cpu30/cache/index1/shared_cpu_list", "15,30"},
290     {"/sys/devices/system/cpu/cpu30/cache/index1/type", "Instruction"},
291     {"/sys/devices/system/cpu/cpu30/cache/index2/shared_cpu_list", "15,30"},
292     {"/sys/devices/system/cpu/cpu30/cache/index2/type", "Unified"},
293     {"/sys/devices/system/cpu/cpu30/cache/index3/shared_cpu_list",
294      "9-16,24-31"},
295     {"/sys/devices/system/cpu/cpu30/cache/index3/type", "Unified"},
296     {"/sys/devices/system/cpu/cpu31/cache/index0/shared_cpu_list", "16,31"},
297     {"/sys/devices/system/cpu/cpu31/cache/index0/type", "Data"},
298     {"/sys/devices/system/cpu/cpu31/cache/index1/shared_cpu_list", "16,31"},
299     {"/sys/devices/system/cpu/cpu31/cache/index1/type", "Instruction"},
300     {"/sys/devices/system/cpu/cpu31/cache/index2/shared_cpu_list", "16,31"},
301     {"/sys/devices/system/cpu/cpu31/cache/index2/type", "Unified"},
302     {"/sys/devices/system/cpu/cpu31/cache/index3/shared_cpu_list",
303      "9-16,24-31"},
304     {"/sys/devices/system/cpu/cpu31/cache/index3/type", "Unified"}};
305
306 /// This is the expected CacheLocality structure for fakeSysfsTree
307 static const CacheLocality nonUniformExampleLocality = {32,
308                                                         {16, 16, 2},
309                                                         {0,
310                                                          2,
311                                                          4,
312                                                          6,
313                                                          8,
314                                                          10,
315                                                          11,
316                                                          12,
317                                                          14,
318                                                          16,
319                                                          18,
320                                                          20,
321                                                          22,
322                                                          24,
323                                                          26,
324                                                          28,
325                                                          30,
326                                                          1,
327                                                          3,
328                                                          5,
329                                                          7,
330                                                          9,
331                                                          13,
332                                                          15,
333                                                          17,
334                                                          19,
335                                                          21,
336                                                          23,
337                                                          25,
338                                                          27,
339                                                          29,
340                                                          31}};
341
342 TEST(CacheLocality, FakeSysfs) {
343   auto parsed = CacheLocality::readFromSysfsTree([](std::string name) {
344     auto iter = fakeSysfsTree.find(name);
345     return iter == fakeSysfsTree.end() ? std::string() : iter->second;
346   });
347
348   auto& expected = nonUniformExampleLocality;
349   EXPECT_EQ(expected.numCpus, parsed.numCpus);
350   EXPECT_EQ(expected.numCachesByLevel, parsed.numCachesByLevel);
351   EXPECT_EQ(expected.localityIndexByCpu, parsed.localityIndexByCpu);
352 }
353
354 #if FOLLY_HAVE_LINUX_VDSO
355 TEST(Getcpu, VdsoGetcpu) {
356   unsigned cpu;
357   Getcpu::resolveVdsoFunc()(&cpu, nullptr, nullptr);
358
359   EXPECT_TRUE(cpu < CPU_SETSIZE);
360 }
361 #endif
362
363 #ifdef FOLLY_TLS
364 TEST(ThreadId, SimpleTls) {
365   unsigned cpu = 0;
366   auto rv =
367       folly::detail::FallbackGetcpu<SequentialThreadId<std::atomic>>::getcpu(
368           &cpu, nullptr, nullptr);
369   EXPECT_EQ(rv, 0);
370   EXPECT_TRUE(cpu > 0);
371   unsigned again;
372   folly::detail::FallbackGetcpu<SequentialThreadId<std::atomic>>::getcpu(
373       &again, nullptr, nullptr);
374   EXPECT_EQ(cpu, again);
375 }
376 #endif
377
378 TEST(ThreadId, SimplePthread) {
379   unsigned cpu = 0;
380   auto rv = folly::detail::FallbackGetcpu<HashingThreadId>::getcpu(
381       &cpu, nullptr, nullptr);
382   EXPECT_EQ(rv, 0);
383   EXPECT_TRUE(cpu > 0);
384   unsigned again;
385   folly::detail::FallbackGetcpu<HashingThreadId>::getcpu(
386       &again, nullptr, nullptr);
387   EXPECT_EQ(cpu, again);
388 }
389
390 #ifdef FOLLY_TLS
391 static FOLLY_TLS unsigned testingCpu = 0;
392
393 static int testingGetcpu(unsigned* cpu, unsigned* node, void* /* unused */) {
394   if (cpu != nullptr) {
395     *cpu = testingCpu;
396   }
397   if (node != nullptr) {
398     *node = testingCpu;
399   }
400   return 0;
401 }
402 #endif
403
404 TEST(AccessSpreader, Simple) {
405   for (size_t s = 1; s < 200; ++s) {
406     EXPECT_LT(AccessSpreader<>::current(s), s);
407   }
408 }
409
410 #ifdef FOLLY_TLS
411 #define DECLARE_SPREADER_TAG(tag, locality, func)      \
412   namespace {                                          \
413   template <typename dummy>                            \
414   struct tag {};                                       \
415   }                                                    \
416   namespace folly {                                    \
417   namespace detail {                                   \
418   template <>                                          \
419   const CacheLocality& CacheLocality::system<tag>() {  \
420     static auto* inst = new CacheLocality(locality);   \
421     return *inst;                                      \
422   }                                                    \
423   template <>                                          \
424   Getcpu::Func AccessSpreader<tag>::pickGetcpuFunc() { \
425     return func;                                       \
426   }                                                    \
427   }                                                    \
428   }
429
430 DECLARE_SPREADER_TAG(ManualTag, CacheLocality::uniform(16), testingGetcpu)
431
432 TEST(AccessSpreader, Wrapping) {
433   // this test won't pass unless locality.numCpus divides kMaxCpus
434   auto numCpus = CacheLocality::system<ManualTag>().numCpus;
435   EXPECT_EQ(0, 128 % numCpus);
436   for (size_t s = 1; s < 200; ++s) {
437     for (size_t c = 0; c < 400; ++c) {
438       testingCpu = c;
439       auto observed = AccessSpreader<ManualTag>::current(s);
440       testingCpu = c % numCpus;
441       auto expected = AccessSpreader<ManualTag>::current(s);
442       EXPECT_EQ(expected, observed) << "numCpus=" << numCpus << ", s=" << s
443                                     << ", c=" << c;
444     }
445   }
446 }
447 #endif